Merge branch 'packer-/impure_team_cvars' into 'master'
authorMario <zacjardine@y7mail.com>
Thu, 9 Jul 2015 01:38:50 +0000 (01:38 +0000)
committerMario <zacjardine@y7mail.com>
Thu, 9 Jul 2015 01:38:50 +0000 (01:38 +0000)
add g_tdm_teams_override and g_domination_teams_override to cvar whitelist

Modifying default team number for gametype tdm or dom makes server impure

g_tdm_teams_override "3" // "0"
g_domination_teams_override "3" // "0"

ca, freezetag and keyhunt are already whitelisted
grep teams_override g_world.qc
BADCVAR("g_ca_teams_override");
BADCVAR("g_freezetag_teams_override");
BADCVAR("g_keyhunt_teams_override");

See merge request !139

186 files changed:
_hud_common.cfg
gfx/menu/luma/crosshairbutton_c.tga [deleted file]
gfx/menu/luma/crosshairbutton_d.tga [deleted file]
gfx/menu/luma/crosshairbutton_f.tga [deleted file]
gfx/menu/luma/crosshairbutton_n.tga [deleted file]
gfx/menu/luma/skinvalues.txt
gfx/menu/luminos/crosshairbutton_c.tga [deleted file]
gfx/menu/luminos/crosshairbutton_d.tga [deleted file]
gfx/menu/luminos/crosshairbutton_f.tga [deleted file]
gfx/menu/luminos/crosshairbutton_n.tga [deleted file]
gfx/menu/luminos/skinvalues.txt
gfx/menu/wickedx/crosshairbutton_c.tga [deleted file]
gfx/menu/wickedx/crosshairbutton_d.tga [deleted file]
gfx/menu/wickedx/crosshairbutton_f.tga [deleted file]
gfx/menu/wickedx/crosshairbutton_n.tga [deleted file]
gfx/menu/wickedx/skinvalues.txt
gfx/menu/xaw/crosshairbutton_c.tga [deleted file]
gfx/menu/xaw/crosshairbutton_d.tga [deleted file]
gfx/menu/xaw/crosshairbutton_f.tga [deleted file]
gfx/menu/xaw/crosshairbutton_n.tga [deleted file]
gfx/menu/xaw/skinvalues.txt
qcsrc/client/_all.qh
qcsrc/client/autocvars.qh
qcsrc/client/command/all.qc [new file with mode: 0644]
qcsrc/client/command/all.qh [new file with mode: 0644]
qcsrc/client/command/commands.qc [deleted file]
qcsrc/client/command/commands.qh [deleted file]
qcsrc/client/damage.qc
qcsrc/client/hud.qc
qcsrc/client/hud.qh
qcsrc/client/hud_config.qc
qcsrc/client/main.qc
qcsrc/client/progs.src
qcsrc/client/t_items.qc
qcsrc/client/vehicles/all.qc [new file with mode: 0644]
qcsrc/client/vehicles/all.qh [new file with mode: 0644]
qcsrc/client/vehicles/vehicles.qc [deleted file]
qcsrc/client/vehicles/vehicles.qh [deleted file]
qcsrc/client/view.qc
qcsrc/client/waypointsprites.qc
qcsrc/common/command/all.qc [new file with mode: 0644]
qcsrc/common/command/all.qh [new file with mode: 0644]
qcsrc/common/command/commands.qc [deleted file]
qcsrc/common/command/commands.qh [deleted file]
qcsrc/common/command/generic.qc
qcsrc/common/constants.qh
qcsrc/common/items/all.inc [new file with mode: 0644]
qcsrc/common/items/all.qc [new file with mode: 0644]
qcsrc/common/items/all.qh [new file with mode: 0644]
qcsrc/common/items/inventory.qh [new file with mode: 0644]
qcsrc/common/items/item.qh [new file with mode: 0644]
qcsrc/common/items/item/ammo.qc [new file with mode: 0644]
qcsrc/common/items/item/ammo.qh [new file with mode: 0644]
qcsrc/common/items/item/armor.qc [new file with mode: 0644]
qcsrc/common/items/item/armor.qh [new file with mode: 0644]
qcsrc/common/items/item/buff.qc [new file with mode: 0644]
qcsrc/common/items/item/buff.qh [new file with mode: 0644]
qcsrc/common/items/item/health.qc [new file with mode: 0644]
qcsrc/common/items/item/health.qh [new file with mode: 0644]
qcsrc/common/items/item/jetpack.qc [new file with mode: 0644]
qcsrc/common/items/item/pickup.qc [new file with mode: 0644]
qcsrc/common/items/item/pickup.qh [new file with mode: 0644]
qcsrc/common/items/item/powerup.qc [new file with mode: 0644]
qcsrc/common/items/item/powerup.qh [new file with mode: 0644]
qcsrc/common/mapinfo.qc
qcsrc/common/monsters/all.qc [new file with mode: 0644]
qcsrc/common/monsters/all.qh [new file with mode: 0644]
qcsrc/common/monsters/monsters.qc [deleted file]
qcsrc/common/monsters/monsters.qh [deleted file]
qcsrc/common/monsters/spawn.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/oo.qh [new file with mode: 0644]
qcsrc/common/playerstats.qc
qcsrc/common/util-pre.qh
qcsrc/common/weapons/all.qc [new file with mode: 0644]
qcsrc/common/weapons/all.qh [new file with mode: 0644]
qcsrc/common/weapons/config.qc
qcsrc/common/weapons/weapons.qc [deleted file]
qcsrc/common/weapons/weapons.qh [deleted file]
qcsrc/menu/_all.qh
qcsrc/menu/classes.inc
qcsrc/menu/command/all.qc [new file with mode: 0644]
qcsrc/menu/command/all.qh [new file with mode: 0644]
qcsrc/menu/command/commands.qc [deleted file]
qcsrc/menu/command/commands.qh [deleted file]
qcsrc/menu/item/container.qc
qcsrc/menu/item/dialog.qc
qcsrc/menu/item/listbox.qc
qcsrc/menu/menu.qc
qcsrc/menu/oo/base.qh
qcsrc/menu/progs.src
qcsrc/menu/skin-customizables.inc
qcsrc/menu/xonotic/campaign.qc
qcsrc/menu/xonotic/charmap.qc
qcsrc/menu/xonotic/credits.qc
qcsrc/menu/xonotic/crosshairbutton.qc [deleted file]
qcsrc/menu/xonotic/crosshairpicker.qc [new file with mode: 0644]
qcsrc/menu/xonotic/crosshairpreview.qc [new file with mode: 0644]
qcsrc/menu/xonotic/cvarlist.qc
qcsrc/menu/xonotic/demolist.qc
qcsrc/menu/xonotic/dialog_multiplayer.qc
qcsrc/menu/xonotic/dialog_multiplayer_create.qc
qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc
qcsrc/menu/xonotic/dialog_multiplayer_join.qc
qcsrc/menu/xonotic/dialog_multiplayer_media.qc
qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc
qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc
qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc
qcsrc/menu/xonotic/dialog_multiplayer_profile.qc
qcsrc/menu/xonotic/dialog_settings_audio.qc
qcsrc/menu/xonotic/dialog_settings_effects.qc
qcsrc/menu/xonotic/dialog_settings_game.qc
qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc
qcsrc/menu/xonotic/dialog_settings_game_hud.qc
qcsrc/menu/xonotic/dialog_settings_game_messages.qc
qcsrc/menu/xonotic/dialog_settings_game_model.qc
qcsrc/menu/xonotic/dialog_settings_game_view.qc
qcsrc/menu/xonotic/dialog_settings_game_weapons.qc
qcsrc/menu/xonotic/dialog_settings_input.qc
qcsrc/menu/xonotic/dialog_settings_misc.qc
qcsrc/menu/xonotic/dialog_settings_user.qc
qcsrc/menu/xonotic/dialog_settings_video.qc
qcsrc/menu/xonotic/gametypelist.qc
qcsrc/menu/xonotic/keybinder.qc
qcsrc/menu/xonotic/languagelist.qc
qcsrc/menu/xonotic/mainwindow.qc
qcsrc/menu/xonotic/maplist.qc
qcsrc/menu/xonotic/picker.qc [new file with mode: 0644]
qcsrc/menu/xonotic/playerlist.qc
qcsrc/menu/xonotic/playlist.qc
qcsrc/menu/xonotic/screenshotlist.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/skinlist.qc
qcsrc/menu/xonotic/soundlist.qc
qcsrc/menu/xonotic/statslist.qc
qcsrc/menu/xonotic/tab.qc
qcsrc/menu/xonotic/util.qc
qcsrc/menu/xonotic/util.qh
qcsrc/menu/xonotic/weaponslist.qc
qcsrc/server/_all.qh
qcsrc/server/bot/bot.qc
qcsrc/server/cheats.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_impulse.qc
qcsrc/server/cl_physics.qc
qcsrc/server/command/all.qc [new file with mode: 0644]
qcsrc/server/command/all.qh [new file with mode: 0644]
qcsrc/server/command/cmd.qc
qcsrc/server/command/commands.qc [deleted file]
qcsrc/server/command/commands.qh [deleted file]
qcsrc/server/command/getreplies.qc
qcsrc/server/command/vote.qc
qcsrc/server/command/vote.qh
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_damage.qh
qcsrc/server/g_hook.qc
qcsrc/server/g_world.qc
qcsrc/server/item_key.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/gamemode.qh
qcsrc/server/mutators/mutator.qh
qcsrc/server/mutators/mutator_instagib.qc
qcsrc/server/mutators/mutators_include.qc
qcsrc/server/portals.qc
qcsrc/server/progs.src
qcsrc/server/sv_main.qc
qcsrc/server/t_items.qc
qcsrc/server/t_items.qh
qcsrc/server/t_plats.qc
qcsrc/server/t_quake.qc
qcsrc/server/t_quake3.qc
qcsrc/server/t_swamp.qc
qcsrc/server/vehicles/all.qh
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/common.qc
qcsrc/server/weapons/csqcprojectile.qc
qcsrc/server/weapons/hitplot.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/spawning.qc
qcsrc/server/weapons/throwing.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponstats.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/warpzonelib/common.qc

index 5aa1bbf..b74eff9 100644 (file)
@@ -38,6 +38,9 @@ seta hud_panel_engineinfo_framecounter_exponentialmovingaverage 1 "use an averag
 seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight 0.1 "weight of latest data point"
 seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold 0.5 "threshold for fps change when to update instantly, to make big fps changes update faster"
 
+seta hud_panel_physics_acceleration_movingaverage 1 "use an averaging method for calculating acceleration instead of the real value"
+seta hud_panel_phisics_update_interval 0.0666 "how often (in seconds) numeric values get updated on screen"
+
 // hud panel aliases
 alias hud_panel_radar_rotate "toggle hud_panel_radar_rotation 0 1 2 3 4"
 alias +hud_panel_radar_maximized "cl_cmd hud radar 1"
diff --git a/gfx/menu/luma/crosshairbutton_c.tga b/gfx/menu/luma/crosshairbutton_c.tga
deleted file mode 100644 (file)
index ecfd0a8..0000000
Binary files a/gfx/menu/luma/crosshairbutton_c.tga and /dev/null differ
diff --git a/gfx/menu/luma/crosshairbutton_d.tga b/gfx/menu/luma/crosshairbutton_d.tga
deleted file mode 100644 (file)
index 4e7901e..0000000
Binary files a/gfx/menu/luma/crosshairbutton_d.tga and /dev/null differ
diff --git a/gfx/menu/luma/crosshairbutton_f.tga b/gfx/menu/luma/crosshairbutton_f.tga
deleted file mode 100644 (file)
index 604a935..0000000
Binary files a/gfx/menu/luma/crosshairbutton_f.tga and /dev/null differ
diff --git a/gfx/menu/luma/crosshairbutton_n.tga b/gfx/menu/luma/crosshairbutton_n.tga
deleted file mode 100644 (file)
index 4e7901e..0000000
Binary files a/gfx/menu/luma/crosshairbutton_n.tga and /dev/null differ
index 1e87e88..5a36d90 100644 (file)
@@ -33,8 +33,10 @@ COLOR_CAMPAIGN_SELECTABLE     '0.96 0.99 1'
 // charmap
 ALPHA_CHARMAP_CHAR            0.85
 COLOR_CHARMAP_CHAR            '1 1 1'
-ALPHA_CHARMAP_FOCUS           0.85
-COLOR_CHARMAP_FOCUS           '0.09 0.42 0.69'
+
+// crosshairpicker
+ALPHA_CROSSHAIRPICKER_CROSSHAIR 0.85
+COLOR_CROSSHAIRPICKER_CROSSHAIR '1 1 1'
 
 // checkbox
 COLOR_CHECKBOX_C              '1 1 1'
@@ -142,6 +144,9 @@ ALPHA_LISTBOX_SELECTED        1
 COLOR_LISTBOX_SELECTED        '0.97 0.56 0.27'
 ALPHA_LISTBOX_WAITING         0.8
 COLOR_LISTBOX_WAITING         '0.73 0.82 0.9'
+ALPHA_LISTBOX_FOCUSED         0.8
+FADEALPHA_LISTBOX_FOCUSED     0.4
+COLOR_LISTBOX_FOCUSED         '0.09 0.42 0.69'
 
 // mainmenu
 ALPHAS_MAINMENU               '0.8 0.9 1'
diff --git a/gfx/menu/luminos/crosshairbutton_c.tga b/gfx/menu/luminos/crosshairbutton_c.tga
deleted file mode 100644 (file)
index 586f9b4..0000000
Binary files a/gfx/menu/luminos/crosshairbutton_c.tga and /dev/null differ
diff --git a/gfx/menu/luminos/crosshairbutton_d.tga b/gfx/menu/luminos/crosshairbutton_d.tga
deleted file mode 100755 (executable)
index cba9d88..0000000
Binary files a/gfx/menu/luminos/crosshairbutton_d.tga and /dev/null differ
diff --git a/gfx/menu/luminos/crosshairbutton_f.tga b/gfx/menu/luminos/crosshairbutton_f.tga
deleted file mode 100644 (file)
index 57d7d93..0000000
Binary files a/gfx/menu/luminos/crosshairbutton_f.tga and /dev/null differ
diff --git a/gfx/menu/luminos/crosshairbutton_n.tga b/gfx/menu/luminos/crosshairbutton_n.tga
deleted file mode 100755 (executable)
index ac94535..0000000
Binary files a/gfx/menu/luminos/crosshairbutton_n.tga and /dev/null differ
index 77af6c8..b9c6980 100755 (executable)
@@ -108,6 +108,9 @@ COLOR_LISTBOX_SELECTED          '1 0.4375 0'
 ALPHA_LISTBOX_SELECTED          1
 COLOR_LISTBOX_WAITING           '1 1 1'
 ALPHA_LISTBOX_WAITING           0.5
+COLOR_LISTBOX_FOCUSED           '0 0.25 0.5'
+ALPHA_LISTBOX_FOCUSED           0.7
+FADEALPHA_LISTBOX_FOCUSED       0.3
 
 // item: map list
 COLOR_MAPLIST_TITLE             '1 1 1'
@@ -170,9 +173,6 @@ COLOR_CHECKBOX_C                '1 1 1'
 COLOR_CHECKBOX_F                '1 1 1'
 COLOR_CHECKBOX_D                '1 1 1'
 
-// item: crosshair button
-//   uses "crosshairbutton" images
-
 // dialog background colors
 //   uses "border" images
 COLOR_DIALOG_MULTIPLAYER        '1 1 1'
@@ -221,8 +221,10 @@ ALPHA_KEYGRABBER_KEYS           0.7
 // item: charmap
 ALPHA_CHARMAP_CHAR              0.85
 COLOR_CHARMAP_CHAR              '1 1 1'
-ALPHA_CHARMAP_FOCUS             1
-COLOR_CHARMAP_FOCUS             '0 0.25 0.5'
+
+// item: crosshairpicker
+ALPHA_CROSSHAIRPICKER_CROSSHAIR 0.85
+COLOR_CROSSHAIRPICKER_CROSSHAIR '1 1 1'
 
 // item: radio button
 //   uses "radiobutton" images
diff --git a/gfx/menu/wickedx/crosshairbutton_c.tga b/gfx/menu/wickedx/crosshairbutton_c.tga
deleted file mode 100644 (file)
index 1c294f7..0000000
Binary files a/gfx/menu/wickedx/crosshairbutton_c.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/crosshairbutton_d.tga b/gfx/menu/wickedx/crosshairbutton_d.tga
deleted file mode 100755 (executable)
index 110faa1..0000000
Binary files a/gfx/menu/wickedx/crosshairbutton_d.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/crosshairbutton_f.tga b/gfx/menu/wickedx/crosshairbutton_f.tga
deleted file mode 100644 (file)
index 0031c35..0000000
Binary files a/gfx/menu/wickedx/crosshairbutton_f.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/crosshairbutton_n.tga b/gfx/menu/wickedx/crosshairbutton_n.tga
deleted file mode 100755 (executable)
index ac94535..0000000
Binary files a/gfx/menu/wickedx/crosshairbutton_n.tga and /dev/null differ
index 8b56baa..09ded4b 100644 (file)
@@ -108,6 +108,9 @@ COLOR_LISTBOX_SELECTED          '0.875 0.375 0'
 ALPHA_LISTBOX_SELECTED          1
 COLOR_LISTBOX_WAITING           '1 1 1'
 ALPHA_LISTBOX_WAITING           0.5
+COLOR_LISTBOX_FOCUSED           '0 0.375 0.75'
+ALPHA_LISTBOX_FOCUSED           0.35
+FADEALPHA_LISTBOX_FOCUSED       0.75
 
 // item: map list
 COLOR_MAPLIST_TITLE             '1 1 1'
@@ -170,9 +173,6 @@ COLOR_CHECKBOX_C                '0.5 0.75 1'
 COLOR_CHECKBOX_F                '0.5 0.75 1'
 COLOR_CHECKBOX_D                '1 1 1'
 
-// item: crosshair button
-//   uses "crosshairbutton" images
-
 // dialog background colors
 //   uses "border" images
 COLOR_DIALOG_MULTIPLAYER        '1 1 1'
@@ -221,8 +221,10 @@ ALPHA_KEYGRABBER_KEYS           0.7
 // item: charmap
 ALPHA_CHARMAP_CHAR              0.85
 COLOR_CHARMAP_CHAR              '1 1 1'
-ALPHA_CHARMAP_FOCUS             0.75
-COLOR_CHARMAP_FOCUS             '0 0.375 0.75'
+
+// item: crosshairpicker
+ALPHA_CROSSHAIRPICKER_CROSSHAIR 0.85
+COLOR_CROSSHAIRPICKER_CROSSHAIR '1 1 1'
 
 // item: radio button
 //   uses "radiobutton" images
diff --git a/gfx/menu/xaw/crosshairbutton_c.tga b/gfx/menu/xaw/crosshairbutton_c.tga
deleted file mode 100644 (file)
index 646c64e..0000000
Binary files a/gfx/menu/xaw/crosshairbutton_c.tga and /dev/null differ
diff --git a/gfx/menu/xaw/crosshairbutton_d.tga b/gfx/menu/xaw/crosshairbutton_d.tga
deleted file mode 100644 (file)
index 110faa1..0000000
Binary files a/gfx/menu/xaw/crosshairbutton_d.tga and /dev/null differ
diff --git a/gfx/menu/xaw/crosshairbutton_f.tga b/gfx/menu/xaw/crosshairbutton_f.tga
deleted file mode 100644 (file)
index d8f25ef..0000000
Binary files a/gfx/menu/xaw/crosshairbutton_f.tga and /dev/null differ
diff --git a/gfx/menu/xaw/crosshairbutton_n.tga b/gfx/menu/xaw/crosshairbutton_n.tga
deleted file mode 100644 (file)
index 5d678a6..0000000
Binary files a/gfx/menu/xaw/crosshairbutton_n.tga and /dev/null differ
index 57c6f2a..00df324 100644 (file)
@@ -107,9 +107,6 @@ ALPHA_CREDITS_PERSON            1
 ROWS_CREDITS                    20
 WIDTH_CREDITS                   0.5
 
-// item: crosshair button
-//   uses "crosshairbutton" images
-
 // item: cvar list
 ALPHA_CVARLIST_SAVED            1
 ALPHA_CVARLIST_TEMPORARY        0.7
@@ -152,8 +149,11 @@ COLOR_LISTBOX_SELECTED          '0 0 0'
 ALPHA_LISTBOX_SELECTED          1
 COLOR_LISTBOX_WAITING           '1 0 0'
 ALPHA_LISTBOX_WAITING           0.5
-COLOR_LISTBOX_BACKGROUND               '0 0 0'
-ALPHA_LISTBOX_BACKGROUND               0
+COLOR_LISTBOX_BACKGROUND        '0 0 0'
+ALPHA_LISTBOX_BACKGROUND        0
+COLOR_LISTBOX_FOCUSED           '0 0 0'
+ALPHA_LISTBOX_FOCUSED           0.3
+FADEALPHA_LISTBOX_FOCUSED       0.3
 
 // item: map list
 COLOR_MAPLIST_TITLE             '1 1 1'
@@ -176,8 +176,10 @@ ALPHA_MODELTITLE                1
 // item: charmap
 ALPHA_CHARMAP_CHAR              0.85
 COLOR_CHARMAP_CHAR              '1 1 1'
-ALPHA_CHARMAP_FOCUS             0.5
-COLOR_CHARMAP_FOCUS             '0 0 0'
+
+// item: crosshairpicker
+ALPHA_CROSSHAIRPICKER_CROSSHAIR 0.85
+COLOR_CROSSHAIRPICKER_CROSSHAIR '1 1 1'
 
 // item: radio button
 //   uses "radiobutton" images
index c8ff79d..e758fdb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef CLIENT___H
-#define CLIENT___H
+#ifndef CLIENT_ALL_H
+#define CLIENT_ALL_H
 
 #include "autocvars.qh"
 #include "defs.qh"
index e35bf82..90faef9 100644 (file)
@@ -282,10 +282,12 @@ float autocvar_hud_panel_notify_fontsize;
 float autocvar_hud_panel_notify_time;
 float autocvar_hud_panel_notify_icon_aspect;
 bool autocvar_hud_panel_physics;
+float autocvar_hud_panel_physics_acceleration_movingaverage = 1;
 float autocvar_hud_panel_physics_acceleration_progressbar_mode;
 float autocvar_hud_panel_physics_acceleration_progressbar_scale;
 float autocvar_hud_panel_physics_acceleration_progressbar_nonlinear;
 float autocvar_hud_panel_physics_acceleration_max;
+float autocvar_hud_panel_physics_update_interval;
 int autocvar_hud_panel_physics_progressbar;
 bool autocvar_hud_panel_physics_acceleration_vertical;
 int autocvar_hud_panel_physics_baralign;
diff --git a/qcsrc/client/command/all.qc b/qcsrc/client/command/all.qc
new file mode 100644 (file)
index 0000000..dcace65
--- /dev/null
@@ -0,0 +1,5 @@
+#include "../_all.qh"
+
+#include "../../common/command/all.qc"
+
+#include "cl_cmd.qc"
diff --git a/qcsrc/client/command/all.qh b/qcsrc/client/command/all.qh
new file mode 100644 (file)
index 0000000..34fc423
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef CLIENT_COMMANDS_ALL_H
+#define CLIENT_COMMANDS_ALL_H
+
+#include "../../common/command/all.qh"
+
+#include "cl_cmd.qh"
+
+#endif
diff --git a/qcsrc/client/command/commands.qc b/qcsrc/client/command/commands.qc
deleted file mode 100644 (file)
index dabf8f3..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "../_all.qh"
-
-#include "../../common/command/commands.qc"
-
-#include "cl_cmd.qc"
diff --git a/qcsrc/client/command/commands.qh b/qcsrc/client/command/commands.qh
deleted file mode 100644 (file)
index 65bf3da..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CLIENT_COMMANDS_H
-#define CLIENT_COMMANDS_H
-
-#include "../../common/command/commands.qh"
-
-#include "cl_cmd.qh"
-
-#endif
index 9241621..39c422e 100644 (file)
@@ -5,13 +5,13 @@
 #include "movetypes.qh"
 #include "prandom.qh"
 
-#include "vehicles/vehicles.qh"
+#include "vehicles/all.qh"
 
 #include "../common/constants.qh"
 #include "../common/deathtypes.qh"
 #include "../common/util.qh"
 
-#include "../common/weapons/weapons.qh"
+#include "../common/weapons/all.qh"
 
 .entity tag_entity;
 
index 33e9cb5..b61fe2a 100644 (file)
@@ -3909,6 +3909,7 @@ void HUD_InfoMessages(void)
 //
 vector acc_prevspeed;
 float acc_prevtime, acc_avg, top_speed, top_speed_time;
+float physics_update_time, discrete_speed, discrete_acceleration;
 void HUD_Physics(void)
 {
        if(!autocvar__hud_configure)
@@ -3996,8 +3997,23 @@ void HUD_Physics(void)
                acc_prevspeed = vel;
                acc_prevtime = time;
 
-               f = bound(0, f * 10, 1);
-               acc_avg = acc_avg * (1 - f) + acceleration * f;
+               if(autocvar_hud_panel_physics_acceleration_movingaverage)
+               {
+                       f = bound(0, f * 10, 1);
+                       acc_avg = acc_avg * (1 - f) + acceleration * f;
+                       acceleration = acc_avg;
+               }
+       }
+
+       int acc_decimals = 2;
+       if(time > physics_update_time)
+       {
+               // workaround for ftos_decimals returning a negative 0
+               if(discrete_acceleration > -1 / pow(10, acc_decimals) && discrete_acceleration < 0)
+                       discrete_acceleration = 0;
+               discrete_acceleration = acceleration;
+               discrete_speed = speed;
+               physics_update_time += autocvar_hud_panel_physics_update_interval;
        }
 
        //compute layout
@@ -4051,7 +4067,7 @@ void HUD_Physics(void)
                //else
                        //tmp_offset_x = 0;
                tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
-               drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(speed), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(discrete_speed), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 
                //draw speed unit
                if (speed_baralign)
@@ -4141,7 +4157,7 @@ void HUD_Physics(void)
 
                f = acceleration/autocvar_hud_panel_physics_acceleration_max;
                if (autocvar_hud_panel_physics_acceleration_progressbar_nonlinear)
-                       f = sqrt(f);
+                       f = (f >= 0 ? sqrt(f) : -sqrt(-f));
 
                if (acceleration_progressbar_scale) // allow progressbar to go out of panel bounds
                {
@@ -4163,12 +4179,16 @@ void HUD_Physics(void)
 
                HUD_Panel_DrawProgressBar(panel_pos + acceleration_offset + tmp_offset, tmp_size, "accelbar", f, 0, acceleration_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
        }
-       tmp_size.x = panel_size.x;
-       tmp_size.y = panel_size.y * text_scale;
-       tmp_offset.x = 0;
-       tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
-       if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3)
-               drawstring_aspect(panel_pos + acceleration_offset + tmp_offset, strcat(ftos_decimals(acceleration, 2), "g"), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+       if(autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3)
+       {
+               tmp_size.x = panel_size.x;
+               tmp_size.y = panel_size.y * text_scale;
+               tmp_offset.x = 0;
+               tmp_offset.y = (panel_size.y - tmp_size.y) / 2;
+
+               drawstring_aspect(panel_pos + acceleration_offset + tmp_offset, strcat(ftos_decimals(discrete_acceleration, acc_decimals), "g"), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       }
 
        draw_endBoldFont();
 }
@@ -4296,15 +4316,23 @@ void HUD_CenterPrint (void)
                        reset_centerprint_messages();
                if (time > hud_configure_cp_generation_time)
                {
-                       float r;
-                       r = random();
-                       if (r > 0.75)
-                               centerprint_generic(floor(r*1000), strcat(sprintf("^3Countdown message at time %s", seconds_tostring(time)), ", seconds left: ^COUNT"), 1, 10);
-                       else if (r > 0.5)
-                               centerprint_generic(0, sprintf("^1Multiline message at time %s that\n^1lasts longer than normal", seconds_tostring(time)), 20, 0);
+                       if(HUD_PANEL(CENTERPRINT) == highlightedPanel)
+                       {
+                               float r;
+                               r = random();
+                               if (r > 0.8)
+                                       centerprint_generic(floor(r*1000), strcat(sprintf("^3Countdown message at time %s", seconds_tostring(time)), ", seconds left: ^COUNT"), 1, 10);
+                               else if (r > 0.55)
+                                       centerprint_generic(0, sprintf("^1Multiline message at time %s that\n^1lasts longer than normal", seconds_tostring(time)), 20, 0);
+                               else
+                                       centerprint_hud(sprintf("Message at time %s", seconds_tostring(time)));
+                               hud_configure_cp_generation_time = time + 1 + random()*4;
+                       }
                        else
-                               centerprint_hud(sprintf("Message at time %s", seconds_tostring(time)));
-                       hud_configure_cp_generation_time = time + 1 + random()*4;
+                       {
+                               centerprint_generic(0, sprintf("Centerprint message", seconds_tostring(time)), 10, 0);
+                               hud_configure_cp_generation_time = time + 10 - random()*3;
+                       }
                }
        }
 
index f880a81..3b61cb4 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef HUD_H
 #define HUD_H
 
-#include "../common/weapons/weapons.qh"
+#include "../common/weapons/all.qh"
 
 const int HUD_PANEL_MAX = 24;
 entity hud_panel[HUD_PANEL_MAX];
@@ -292,27 +292,18 @@ HUD_PANELS(HUD_PANEL)
 } while(0)
 
 // return smoothly faded pos and size of given panel when a dialog is active
-#define HUD_Panel_UpdatePosSize_ForMenu() do {                                                                      \
-       vector menu_enable_pos;                                                                                         \
-       vector menu_enable_size = '0 0 0';                                                                              \
-       float menu_enable_maxsize_x = 0.3 * vid_conwidth;                                                               \
-       float menu_enable_maxsize_y = 0.18 * vid_conheight;                                                             \
-       if (panel_size.x > panel_size.y) {                                                                              \
-               if (panel_size.y > menu_enable_maxsize_y) {                                                                 \
-                       menu_enable_size.y = menu_enable_maxsize_y;                                                             \
-                       menu_enable_size.x = panel_size.x * (menu_enable_maxsize_y/panel_size.y);                               \
-                       panel_size = (1 - autocvar__menu_alpha) * panel_size + (autocvar__menu_alpha) * menu_enable_size;       \
-               }                                                                                                           \
-               menu_enable_pos = eX * 0.5 * vid_conwidth - eX * 0.5 * panel_size.x + eY * (vid_conheight - menu_enable_maxsize_y);\
-       } else {                                                                                                        \
-               if (panel_size.x > menu_enable_maxsize_x) {                                                                 \
-                       menu_enable_size.x = menu_enable_maxsize_x;                                                             \
-                       menu_enable_size.y = panel_size.y * (menu_enable_maxsize_x/panel_size.x);                               \
-                       panel_size = (1 - autocvar__menu_alpha) * panel_size + (autocvar__menu_alpha) * menu_enable_size;       \
-               }                                                                                                           \
-               menu_enable_pos = eY * 0.5 * vid_conheight - eY * 0.5 * panel_size.y + eX * (vid_conwidth - menu_enable_maxsize_x);\
-       }                                                                                                               \
-       panel_pos = (1 - autocvar__menu_alpha) * panel_pos + (autocvar__menu_alpha) * menu_enable_pos;                  \
+// don't center too wide panels, it doesn't work with different resolutions
+#define HUD_Panel_UpdatePosSize_ForMenu() do { \
+       vector menu_enable_size = panel_size; \
+       float max_panel_width = 0.52 * vid_conwidth; \
+       if(panel_size.x > max_panel_width) \
+       { \
+               menu_enable_size.x = max_panel_width; \
+               menu_enable_size.y = panel_size.y * (menu_enable_size.x / panel_size.x); \
+       } \
+       vector menu_enable_pos = eX * (panel_bg_border + 0.5 * max_panel_width) + eY * 0.5 * vid_conheight - 0.5 * menu_enable_size; \
+       panel_pos = (1 - autocvar__menu_alpha) * panel_pos + (autocvar__menu_alpha) * menu_enable_pos; \
+       panel_size = (1 - autocvar__menu_alpha) * panel_size + (autocvar__menu_alpha) * menu_enable_size; \
 } while(0)
 
 // Scale the pos and size vectors to absolute coordinates
index 3352e64..4b55bb4 100644 (file)
@@ -431,8 +431,7 @@ void HUD_Panel_SetPosSize(vector mySize)
 {
        panel = highlightedPanel;
        HUD_Panel_UpdatePosSize();
-       vector resizeorigin;
-       resizeorigin = panel_click_resizeorigin;
+       vector resizeorigin = panel_click_resizeorigin;
        vector myPos;
 
        // minimum panel size cap
@@ -565,7 +564,6 @@ void HUD_Panel_Arrow_Action(float nPrimary)
 
        if (hudShiftState & S_ALT) // resize
        {
-               highlightedAction = 1;
                if(nPrimary == K_UPARROW)
                        resizeCorner = 1;
                else if(nPrimary == K_RIGHTARROW)
@@ -602,7 +600,6 @@ void HUD_Panel_Arrow_Action(float nPrimary)
        }
        else // move
        {
-               highlightedAction = 2;
                vector pos;
                pos = panel_pos;
                if(nPrimary == K_UPARROW)
@@ -744,15 +741,14 @@ float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
                if (!menu_enabled)
                        cvar_set("_hud_configure", "0");
        }
-       else if(nPrimary == K_TAB && hudShiftState & S_CTRL) // select and highlight another panel
+       else if(nPrimary == K_TAB && hudShiftState & S_CTRL) // switch panel
        {
                if (bInputType == 1 || mouseClicked)
                        return true;
 
-               //FIXME: if a panel is highlighted, has the same pos_x and lays in the same level
-               //of other panels then next consecutive ctrl-tab will select the highlighted panel too
-               //(it should only after every other panel of the hud)
-               //It's a minor bug anyway, we can live with it
+               // FIXME minor bug: if a panel is highlighted, has the same pos_x and
+               // lays in the same level of another panel then the next consecutive
+               // CTRL TAB presses will reselect once more the highlighted panel
 
                entity starting_panel;
                entity old_tab_panel = tab_panel;
@@ -897,6 +893,12 @@ float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
                        highlightedPanel_backup = world;
                }
        }
+       else if(nPrimary == 's' && hudShiftState & S_CTRL) // save config
+       {
+               if (bInputType == 1 || mouseClicked)
+                       return true;
+               localcmd("hud save myconfig\n");
+       }
        else if(nPrimary == K_UPARROW || nPrimary == K_DOWNARROW || nPrimary == K_LEFTARROW || nPrimary == K_RIGHTARROW)
        {
                if (bInputType == 1)
@@ -917,7 +919,7 @@ float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
                if (highlightedPanel)
                        HUD_Panel_EnableMenu();
        }
-       else if(hit_con_bind)
+       else if(hit_con_bind || nPrimary == K_PAUSE)
                return false;
 
        return true;
@@ -1176,6 +1178,8 @@ void HUD_Panel_Mouse()
        }
        else
        {
+               if(prevMouseClicked)
+                       highlightedAction = 0;
                if(menu_enabled == 2)
                        mouse_over_panel = 0;
                else
index 5343c18..7648b12 100644 (file)
 #include "waypointsprites.qh"
 
 #include "vehicles/bumblebee.qh"
-#include "vehicles/vehicles.qh"
+#include "vehicles/all.qh"
 
 #include "weapons/projectile.qh"
 
 #include "../common/buffs.qh"
 #include "../common/deathtypes.qh"
 #include "../common/mapinfo.qh"
-#include "../common/monsters/monsters.qh"
+#include "../common/monsters/all.qh"
 #include "../common/nades.qh"
 #include "../common/net_notice.qh"
 #include "../common/notifications.qh"
 #include "../common/stats.qh"
 #include "../common/teams.qh"
 
-#include "../common/weapons/weapons.qh"
+#include "../common/items/all.qh"
+
+#include "../common/weapons/all.qh"
 
 #include "../csqcmodellib/cl_model.qh"
 #include "../csqcmodellib/interpolate.qh"
@@ -136,6 +138,7 @@ void CSQC_Init(void)
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
        CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
+       CALL_ACCUMULATED_FUNCTION(RegisterItems);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
@@ -856,6 +859,7 @@ void CSQC_Ent_Update(float bIsNewEntity)
                case ENT_CLIENT_WARPZONE_TELEPORTED: WarpZone_Teleported_Read(bIsNewEntity); break;
                case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break;
                case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break;
+               case ENT_CLIENT_INVENTORY: Inventory_Read(self); break;
                case ENT_CLIENT_ARC_BEAM: Ent_ReadArcBeam(bIsNewEntity); break;
                case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
                case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
index 36d159c..8ba12b9 100644 (file)
@@ -37,10 +37,10 @@ view.qc
 wall.qc
 waypointsprites.qc
 
-command/commands.qc
+command/all.qc
 
 vehicles/bumblebee.qc
-vehicles/vehicles.qc
+vehicles/all.qc
 
 weapons/projectile.qc // TODO
 
@@ -55,9 +55,11 @@ weapons/projectile.qc // TODO
 ../common/urllib.qc
 ../common/util.qc
 
-../common/monsters/monsters.qc
+../common/items/all.qc
 
-../common/weapons/weapons.qc // TODO
+../common/monsters/all.qc
+
+../common/weapons/all.qc // TODO
 
 ../csqcmodellib/cl_model.qc
 ../csqcmodellib/cl_player.qc
index f9ebb97..ca631fc 100644 (file)
@@ -3,7 +3,7 @@
 #include "movetypes.qh"
 #include "../common/buffs.qh"
 #include "../common/util.qh"
-#include "../common/weapons/weapons.qh"
+#include "../common/weapons/all.qh"
 #include "../csqcmodellib/cl_model.qh"
 #include "../csqcmodellib/common.qh"
 
diff --git a/qcsrc/client/vehicles/all.qc b/qcsrc/client/vehicles/all.qc
new file mode 100644 (file)
index 0000000..0af4d4b
--- /dev/null
@@ -0,0 +1,1054 @@
+#include "all.qh"
+#include "../_all.qh"
+
+#include "../movetypes.qh"
+#include "../movetypes.qh"
+#include "../prandom.qh"
+#include "../scoreboard.qh"
+#include "../t_items.qh"
+
+#include "../../common/buffs.qh"
+#include "../../common/constants.qh"
+#include "../../common/stats.qh"
+#include "../../common/util.qh"
+
+#include "../../csqcmodellib/cl_model.qh"
+
+.float cnt;
+
+const string hud_bg = "gfx/vehicles/frame.tga";
+const string hud_sh = "gfx/vehicles/vh-shield.tga";
+
+const string hud_hp_bar = "gfx/vehicles/bar_up_left.tga";
+const string hud_hp_ico = "gfx/vehicles/health.tga";
+const string hud_sh_bar = "gfx/vehicles/bar_dwn_left.tga";
+const string hud_sh_ico = "gfx/vehicles/shield.tga";
+
+const string hud_ammo1_bar = "gfx/vehicles/bar_up_right.tga";
+const string hud_ammo1_ico = "gfx/vehicles/bullets.tga";
+const string hud_ammo2_bar = "gfx/vehicles/bar_dwn_right.tga";
+const string hud_ammo2_ico = "gfx/vehicles/rocket.tga";
+const string hud_energy = "gfx/vehicles/energy.tga";
+
+const int SBRM_FIRST = 1;
+const int SBRM_VOLLY = 1;
+const int SBRM_GUIDE = 2;
+const int SBRM_ARTILLERY = 3;
+const int SBRM_LAST = 3;
+
+const int RSM_FIRST = 1;
+const int RSM_BOMB = 1;
+const int RSM_FLARE = 2;
+const int RSM_LAST = 2;
+
+entity dropmark;
+float autocvar_cl_vehicles_hudscale = 0.5;
+float autocvar_cl_vehicles_hudalpha = 0.75;
+
+const string raptor_ico =  "gfx/vehicles/raptor.tga";
+const string raptor_gun =  "gfx/vehicles/raptor_guns.tga";
+const string raptor_bomb = "gfx/vehicles/raptor_bombs.tga";
+const string raptor_drop = "gfx/vehicles/axh-dropcross.tga";
+string raptor_xhair;
+
+
+
+const int MAX_AXH = 4;
+entity AuxiliaryXhairs[MAX_AXH];
+
+entityclass(AuxiliaryXhair);
+class(AuxiliaryXhair) .string axh_image;
+class(AuxiliaryXhair) .float  axh_fadetime;
+class(AuxiliaryXhair) .float  axh_drawflag;
+class(AuxiliaryXhair) .float  axh_scale;
+
+const string bumb_ico =  "gfx/vehicles/bumb.tga";
+const string bumb_lgun =  "gfx/vehicles/bumb_lgun.tga";
+const string bumb_rgun =  "gfx/vehicles/bumb_rgun.tga";
+
+const string bumb_gun_ico =  "gfx/vehicles/bumb_side.tga";
+const string bumb_gun_gun =  "gfx/vehicles/bumb_side_gun.tga";
+
+const string spider_ico =  "gfx/vehicles/sbot.tga";
+const string spider_rkt =  "gfx/vehicles/sbot_rpods.tga";
+const string spider_mgun = "gfx/vehicles/sbot_mguns.tga";
+string spider_xhair; // = "gfx/vehicles/axh-special1.tga";
+
+const string waki_ico = "gfx/vehicles/waki.tga";
+const string waki_eng = "gfx/vehicles/waki_e.tga";
+const string waki_gun = "gfx/vehicles/waki_guns.tga";
+const string waki_rkt = "gfx/vehicles/waki_rockets.tga";
+const string waki_xhair = "gfx/vehicles/axh-special1.tga";
+
+float alarm1time;
+float alarm2time;
+int weapon2mode;
+
+void AuxiliaryXhair_Draw2D()
+{
+    vector loc, psize;
+
+    psize = self.axh_scale * draw_getimagesize(self.axh_image);
+    loc = project_3d_to_2d(self.move_origin) - 0.5 * psize;
+    if (!(loc.z < 0 || loc.x < 0 || loc.y < 0 || loc.x > vid_conwidth || loc.y > vid_conheight))
+    {
+        loc.z = 0;
+        psize.z = 0;
+        drawpic(loc, self.axh_image, psize, self.colormod, self.alpha, self.axh_drawflag);
+    }
+
+    if(time - self.cnt > self.axh_fadetime)
+        self.draw2d = func_null;
+}
+
+void Net_AuXair2(bool bIsNew)
+{
+    int axh_id = bound(0, ReadByte(), MAX_AXH);
+    entity axh                 = AuxiliaryXhairs[axh_id];
+
+    if(axh == world || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
+    {
+        axh                                    = spawn();
+               axh.draw2d                      = func_null;
+               axh.drawmask            = MASK_NORMAL;
+               axh.axh_drawflag        = DRAWFLAG_ADDITIVE;
+               axh.axh_fadetime        = 0.1;
+               axh.axh_image           = "gfx/vehicles/axh-ring.tga";
+               axh.axh_scale           = 1;
+        axh.alpha                      = 1;
+               AuxiliaryXhairs[axh_id] = axh;
+    }
+
+       axh.move_origin_x = ReadCoord();
+       axh.move_origin_y = ReadCoord();
+       axh.move_origin_z = ReadCoord();
+       axh.colormod_x = ReadByte() / 255;
+       axh.colormod_y = ReadByte() / 255;
+       axh.colormod_z = ReadByte() / 255;
+    axh.cnt                    = time;
+    axh.draw2d                 = AuxiliaryXhair_Draw2D;
+}
+
+void Net_VehicleSetup()
+{
+    int hud_id = ReadByte();
+
+    // Weapon update?
+    if(hud_id > HUD_VEHICLE_LAST)
+    {
+        weapon2mode = hud_id - HUD_VEHICLE_LAST;
+        return;
+    }
+
+    // hud_id == 0 means we exited a vehicle, so stop alarm sound/s
+    if(hud_id == 0)
+    {
+        sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+        sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+        return;
+    }
+
+    hud_id  = bound(HUD_VEHICLE_FIRST, hud_id, HUD_VEHICLE_LAST);
+
+    // Init auxiliary crosshairs
+    int i;
+    for(i = 0; i < MAX_AXH; ++i)
+    {
+        entity axh = AuxiliaryXhairs[i];
+        if(axh != world && !wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
+            remove(axh);
+
+        axh                                    = spawn();
+               axh.draw2d                      = func_null;
+               axh.drawmask            = MASK_NORMAL;
+               axh.axh_drawflag        = DRAWFLAG_NORMAL;
+               axh.axh_fadetime        = 0.1;
+               axh.axh_image           = "gfx/vehicles/axh-ring.tga";
+               axh.axh_scale           = 1;
+        axh.alpha                      = 1;
+               AuxiliaryXhairs[i]      = axh;
+    }
+
+    switch(hud_id)
+    {
+        case HUD_SPIDERBOT:
+            // Minigun1
+            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-ring.tga";
+            AuxiliaryXhairs[0].axh_scale   = 0.25;
+            // Minigun2
+            AuxiliaryXhairs[1].axh_image   = "gfx/vehicles/axh-ring.tga";
+            AuxiliaryXhairs[1].axh_scale   = 0.25;
+            // Rocket
+            AuxiliaryXhairs[2].axh_image   = "gfx/vehicles/axh-special1.tga";
+            AuxiliaryXhairs[2].axh_scale   = 0.5;
+            break;
+
+        case HUD_WAKIZASHI:
+            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-bracket.tga";
+            AuxiliaryXhairs[0].axh_scale   = 0.25;
+            break;
+
+        case HUD_RAPTOR:
+            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-special2.tga";
+            AuxiliaryXhairs[0].axh_scale   = 0.5;
+            //AuxiliaryXhair[0].alpha       = 0.5;
+
+            AuxiliaryXhairs[1].axh_image   = "gfx/vehicles/axh-bracket.tga";
+            AuxiliaryXhairs[1].axh_scale   = 0.25;
+            //AuxiliaryXhair[1].alpha       = 0.75;
+            //AuxiliaryXhair[1].axh_drawflag  = DRAWFLAG_NORMAL;
+            break;
+
+        case HUD_BUMBLEBEE:
+            // Raygun-locked
+            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-bracket.tga";
+            AuxiliaryXhairs[0].axh_scale   = 0.5;
+
+            // Gunner1
+            AuxiliaryXhairs[1].axh_image   = "gfx/vehicles/axh-target.tga";
+            AuxiliaryXhairs[1].axh_scale   = 0.75;
+
+            // Gunner2
+            AuxiliaryXhairs[2].axh_image   = "gfx/vehicles/axh-target.tga";
+            AuxiliaryXhairs[2].axh_scale   = 0.75;
+            break;
+        case HUD_BUMBLEBEE_GUN:
+            // Plasma cannons
+            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-bracket.tga";
+            AuxiliaryXhairs[0].axh_scale   = 0.25;
+            // Raygun
+            AuxiliaryXhairs[1].axh_image   = "gfx/vehicles/axh-bracket.tga";
+            AuxiliaryXhairs[1].axh_scale   = 0.25;
+            break;
+    }
+}
+#define HUD_GETSTATS \
+    int vh_health       = getstati(STAT_VEHICLESTAT_HEALTH);  \
+       float shield        = getstati(STAT_VEHICLESTAT_SHIELD);  \
+       noref int energy    = getstati(STAT_VEHICLESTAT_ENERGY);  \
+       noref float ammo1   = getstati(STAT_VEHICLESTAT_AMMO1);   \
+       noref float reload1 = getstati(STAT_VEHICLESTAT_RELOAD1); \
+       noref int ammo2     = getstati(STAT_VEHICLESTAT_AMMO2);   \
+       noref int reload2   = getstati(STAT_VEHICLESTAT_RELOAD2);
+
+void CSQC_BUMBLE_HUD()
+{
+/*
+    drawpic(hudloc, waki_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_b, picsize, '0 1 0' * health + '1 0 0'  * (1 - health), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_r, picsize, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0'  * (1 - energy), 1, DRAWFLAG_NORMAL);
+*/
+       if(autocvar_r_letterbox)
+        return;
+
+    vector picsize, hudloc = '0 0 0', pic2size, picloc;
+
+    // Fetch health & ammo stats
+       HUD_GETSTATS
+
+    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
+    hudloc.y = vid_conheight - picsize.y;
+    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
+
+    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
+
+    shield  *= 0.01;
+    vh_health  *= 0.01;
+    energy  *= 0.01;
+    reload1 *= 0.01;
+
+    pic2size = draw_getimagesize(bumb_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
+    picloc = picsize * 0.5 - pic2size * 0.5;
+
+    if(vh_health < 0.25)
+        drawpic(hudloc + picloc, bumb_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, bumb_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
+
+    drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
+
+// Health bar
+    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
+    if(vh_health < 0.25)
+    {
+        if(alarm1time < time)
+        {
+            alarm1time = time + 2;
+            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm1time)
+        {
+            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm1time = 0;
+        }
+    }
+
+// Shield bar
+    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
+    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
+    if(shield < 0.25)
+    {
+        if(alarm2time < time)
+        {
+            alarm2time = time + 1;
+            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm2time)
+        {
+            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm2time = 0;
+        }
+    }
+
+       ammo1 *= 0.01;
+       ammo2 *= 0.01;
+
+// Gunner1 bar
+    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * ammo1, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+
+// Right gunner slot occupied?
+       if(!AuxiliaryXhairs[1].draw2d)
+       {
+               shield = (picsize.x * 0.5) - (0.5 * stringwidth(_("No right gunner!"), false, '1 0 0' * picsize.y + '0 1 0' * picsize.y));
+               drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL);
+               drawstring(hudloc + picloc + '1 0 0' * shield, _("No right gunner!"), '1 0 0' * picsize.y + '0 1 0' * picsize.y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL);
+       }
+
+// ..  and icon
+    picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
+    if(ammo1 < 0.2)
+        drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+// Gunner2 bar
+    picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * ammo2, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// Left gunner slot occupied?
+       if(!AuxiliaryXhairs[2].draw2d)
+       {
+               shield = (picsize.x * 0.5) - (0.5 * stringwidth(_("No left gunner!"), false, '1 0 0' * picsize.y + '0 1 0' * picsize.y));
+               drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL);
+               drawstring(hudloc + picloc + '1 0 0' * shield, _("No left gunner!"), '1 0 0' * picsize.y + '0 1 0' * picsize.y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL);
+       }
+
+// ..  and icon
+    picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
+    if(ammo2 < 0.2)
+        drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+       if (scoreboard_showscores)
+               HUD_DrawScoreboard();
+    else
+    {
+        picsize = draw_getimagesize(waki_xhair);
+        picsize.x *= 0.5;
+        picsize.y *= 0.5;
+        drawpic('0.5 0 0' * (vid_conwidth - picsize.x) + '0 0.5 0' * (vid_conheight - picsize.y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    }
+
+}
+
+void CSQC_BUMBLE_GUN_HUD()
+{
+
+       if(autocvar_r_letterbox)
+        return;
+
+    vector picsize, hudloc = '0 0 0', pic2size, picloc;
+
+    // Fetch health & ammo stats
+       HUD_GETSTATS
+
+    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
+    hudloc.y = vid_conheight - picsize.y;
+    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
+
+    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
+
+    shield  *= 0.01;
+    vh_health  *= 0.01;
+    energy  *= 0.01;
+    reload1 *= 0.01;
+
+    pic2size = draw_getimagesize(bumb_gun_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
+    picloc = picsize * 0.5 - pic2size * 0.5;
+
+    if(vh_health < 0.25)
+        drawpic(hudloc + picloc, bumb_gun_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, bumb_gun_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
+
+    drawpic(hudloc + picloc, bumb_gun_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
+
+// Health bar
+    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
+    if(vh_health < 0.25)
+    {
+        if(alarm1time < time)
+        {
+            alarm1time = time + 2;
+            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm1time)
+        {
+            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm1time = 0;
+        }
+    }
+
+// Shield bar
+    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
+    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
+    if(shield < 0.25)
+    {
+        if(alarm2time < time)
+        {
+            alarm2time = time + 1;
+            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm2time)
+        {
+            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm2time = 0;
+        }
+    }
+
+// Gun bar
+    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * energy, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+
+// ..  and icon
+    picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
+    if(energy < 0.2)
+        drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+       if (scoreboard_showscores)
+               HUD_DrawScoreboard();
+    /*
+    else
+    {
+        picsize = draw_getimagesize(waki_xhair);
+        picsize_x *= 0.5;
+        picsize_y *= 0.5;
+
+
+        drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    }
+    */
+}
+
+
+
+void CSQC_SPIDER_HUD()
+{
+       if(autocvar_r_letterbox)
+        return;
+
+    vector picsize, hudloc = '0 0 0', pic2size, picloc;
+    int i;
+
+    // Fetch health & ammo stats
+       HUD_GETSTATS
+
+    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
+    hudloc.y = vid_conheight - picsize.y;
+    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
+
+    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
+
+    ammo1   *= 0.01;
+    shield  *= 0.01;
+    vh_health  *= 0.01;
+    reload2 *= 0.01;
+
+    pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
+    picloc = picsize * 0.5 - pic2size * 0.5;
+    if(vh_health < 0.25)
+        drawpic(hudloc + picloc, spider_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, spider_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, spider_rkt, pic2size,  '1 1 1' * reload2 + '1 0 0' * (1 - reload2), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, spider_mgun, pic2size, '1 1 1' * ammo1   + '1 0 0' * (1 - ammo1),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
+
+// Health bar
+    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
+    if(vh_health < 0.25)
+    {
+        if(alarm1time < time)
+        {
+            alarm1time = time + 2;
+            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm1time)
+        {
+            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm1time = 0;
+        }
+    }
+// Shield bar
+    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
+    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
+    if(shield < 0.25)
+    {
+        if(alarm2time < time)
+        {
+            alarm2time = time + 1;
+            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm2time)
+        {
+            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm2time = 0;
+        }
+    }
+
+// Minigun bar
+    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * ammo1, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
+    if(ammo1 < 0.2)
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+// Rocket ammo bar
+    picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
+    ammo1 = picsize.x / 8;
+    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, hudloc.y + picloc.y, picsize.x * reload2, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+
+// ..  and icons
+    pic2size = 0.35 * draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
+    picloc.x -= pic2size.x;
+    picloc.y += pic2size.y * 2.25;
+    if(ammo2 == 9)
+    {
+        for(i = 1; i < 9; ++i)
+        {
+            picloc.x += ammo1;
+            drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((8 * reload2 <= i) ? '0 0 0' : '1 1 1'), 0.75, DRAWFLAG_NORMAL);
+        }
+    }
+    else
+    {
+        for(i = 1; i < 9; ++i)
+        {
+            picloc.x += ammo1;
+            drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((i >= ammo2) ? '1 1 1' : '0 0 0'), 0.75, DRAWFLAG_NORMAL);
+        }
+    }
+    pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
+    if(ammo2 == 9)
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+       if (scoreboard_showscores)
+               HUD_DrawScoreboard();
+    else
+    {
+        switch(weapon2mode)
+        {
+            case SBRM_VOLLY:
+                spider_xhair = "gfx/vehicles/axh-bracket.tga";
+                break;
+            case SBRM_GUIDE:
+                spider_xhair = "gfx/vehicles/axh-cross.tga";
+                break;
+            case SBRM_ARTILLERY:
+                spider_xhair = "gfx/vehicles/axh-tag.tga";
+                break;
+            default:
+                spider_xhair= "gfx/vehicles/axh-tag.tga";
+        }
+
+        picsize = draw_getimagesize(spider_xhair);
+        picsize.x *= autocvar_cl_vehicle_spiderbot_cross_size;
+        picsize.y *= autocvar_cl_vehicle_spiderbot_cross_size;
+
+        drawpic('0.5 0 0' * (vid_conwidth - picsize.x) + '0 0.5 0' * (vid_conheight - picsize.y), spider_xhair, picsize, '1 1 1', autocvar_cl_vehicle_spiderbot_cross_alpha, DRAWFLAG_ADDITIVE);
+    }
+}
+
+void CSQC_RAPTOR_HUD()
+{
+       if(autocvar_r_letterbox)
+        return;
+
+    vector picsize, hudloc = '0 0 0', pic2size, picloc;
+
+    // Fetch health & ammo stats
+       HUD_GETSTATS
+
+    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
+    hudloc.y = vid_conheight - picsize.y;
+    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
+
+    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
+
+    ammo1   *= 0.01;
+    ammo2   *= 0.01;
+    shield  *= 0.01;
+    vh_health  *= 0.01;
+    energy  *= 0.01;
+    reload1 = reload2 * 0.01;
+    //reload2 *= 0.01;
+
+    pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
+    picloc = picsize * 0.5 - pic2size * 0.5;
+    if(vh_health < 0.25)
+        drawpic(hudloc + picloc, raptor_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, raptor_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, raptor_bomb, pic2size,  '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, raptor_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
+
+// Health bar
+    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
+    if(vh_health < 0.25)
+    {
+        if(alarm1time < time)
+        {
+            alarm1time = time + 2;
+            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm1time)
+        {
+            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm1time = 0;
+        }
+    }
+
+// Shield bar
+    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
+    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
+    if(shield < 0.25)
+    {
+        if(alarm2time < time)
+        {
+            alarm2time = time + 1;
+            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm2time)
+        {
+            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm2time = 0;
+        }
+    }
+
+// Gun bar
+    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * energy, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
+    if(energy < 0.2)
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+// Bomb bar
+    picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, hudloc.y + picloc.y, picsize.x * reload1, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
+    if(reload1 != 1)
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+    if(weapon2mode == RSM_FLARE)
+    {
+        raptor_xhair =  "gfx/vehicles/axh-bracket.tga";
+    }
+    else
+    {
+        raptor_xhair =  "gfx/vehicles/axh-ring.tga";
+
+        // Bombing crosshair
+        if(!dropmark)
+        {
+            dropmark = spawn();
+            dropmark.owner = self;
+            dropmark.gravity = 1;
+        }
+
+        if(reload2 == 100)
+        {
+            vector where;
+
+            setorigin(dropmark, pmove_org);
+            dropmark.velocity = pmove_vel;
+            tracetoss(dropmark, self);
+
+            where = project_3d_to_2d(trace_endpos);
+
+            setorigin(dropmark, trace_endpos);
+            picsize = draw_getimagesize(raptor_drop) * 0.2;
+
+            if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight))
+            {
+                where.x -= picsize.x * 0.5;
+                where.y -= picsize.y * 0.5;
+                where.z = 0;
+                drawpic(where, raptor_drop, picsize, '0 2 0', 1, DRAWFLAG_ADDITIVE);
+            }
+            dropmark.cnt = time + 5;
+        }
+        else
+        {
+            vector where;
+            if(dropmark.cnt > time)
+            {
+                where = project_3d_to_2d(dropmark.origin);
+                picsize = draw_getimagesize(raptor_drop) * 0.25;
+
+                if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight))
+                {
+                    where.x -= picsize.x * 0.5;
+                    where.y -= picsize.y * 0.5;
+                    where.z = 0;
+                    drawpic(where, raptor_drop, picsize, '2 0 0', 1, DRAWFLAG_ADDITIVE);
+                }
+            }
+        }
+    }
+
+       if (scoreboard_showscores)
+               HUD_DrawScoreboard();
+    else
+    {
+        picsize = draw_getimagesize(raptor_xhair);
+        picsize.x *= 0.5;
+        picsize.y *= 0.5;
+
+        drawpic('0.5 0 0' * (vid_conwidth - picsize.x) + '0 0.5 0' * (vid_conheight - picsize.y), raptor_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    }
+}
+
+void CSQC_WAKIZASHI_HUD()
+{
+/*
+    drawpic(hudloc, waki_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_b, picsize, '0 1 0' * health + '1 0 0'  * (1 - health), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_r, picsize, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0'  * (1 - energy), 1, DRAWFLAG_NORMAL);
+*/
+       if(autocvar_r_letterbox)
+        return;
+
+    vector picsize, hudloc = '0 0 0', pic2size, picloc;
+
+    // Fetch health & ammo stats
+       HUD_GETSTATS
+
+    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
+    hudloc.y = vid_conheight - picsize.y;
+    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
+
+    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
+
+    shield  *= 0.01;
+    vh_health  *= 0.01;
+    energy  *= 0.01;
+    reload1 *= 0.01;
+
+    pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
+    picloc = picsize * 0.5 - pic2size * 0.5;
+    if(vh_health < 0.25)
+        drawpic(hudloc + picloc, waki_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, waki_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, waki_eng, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, waki_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, waki_rkt, pic2size,  '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
+
+// Health bar
+    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
+    if(vh_health < 0.25)
+    {
+        if(alarm1time < time)
+        {
+            alarm1time = time + 2;
+            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm1time)
+        {
+            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm1time = 0;
+        }
+    }
+
+
+// Shield bar
+    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
+    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
+    if(shield < 0.25)
+    {
+        if(alarm2time < time)
+        {
+            alarm2time = time + 1;
+            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm2time)
+        {
+            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
+            alarm2time = 0;
+        }
+    }
+
+// Gun bar
+    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * energy, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
+    if(energy < 0.2)
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+// Bomb bar
+    picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc.x + picloc.x, hudloc.y + picloc.y, picsize.x * reload1, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
+    if(reload1 != 1)
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+       if (scoreboard_showscores)
+               HUD_DrawScoreboard();
+    else
+    {
+        picsize = draw_getimagesize(waki_xhair);
+        picsize.x *= 0.5;
+        picsize.y *= 0.5;
+
+
+        drawpic('0.5 0 0' * (vid_conwidth - picsize.x) + '0 0.5 0' * (vid_conheight - picsize.y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    }
+}
+
+void Vehicles_Precache()
+{
+       precache_model("models/vehicles/bomblet.md3");
+       precache_model("models/vehicles/clusterbomb.md3");
+       precache_model("models/vehicles/clusterbomb_fragment.md3");
+       precache_model("models/vehicles/rocket01.md3");
+       precache_model("models/vehicles/rocket02.md3");
+
+       precache_sound ("vehicles/alarm.wav");
+       precache_sound ("vehicles/alarm_shield.wav");
+}
+
+void RaptorCBShellfragDraw()
+{
+       if(wasfreed(self))
+               return;
+
+       Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
+       self.move_avelocity += randomvec() * 15;
+       self.renderflags = 0;
+
+       if(self.cnt < time)
+               self.alpha = bound(0, self.nextthink - time, 1);
+
+       if(self.alpha < ALPHA_MIN_VISIBLE)
+        remove(self);
+}
+
+void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
+{
+    entity sfrag;
+
+    sfrag = spawn();
+    setmodel(sfrag, "models/vehicles/clusterbomb_fragment.md3");
+    setorigin(sfrag, _org);
+
+       sfrag.move_movetype = MOVETYPE_BOUNCE;
+       sfrag.gravity = 0.15;
+       sfrag.solid = SOLID_CORPSE;
+
+       sfrag.draw = RaptorCBShellfragDraw;
+
+       sfrag.move_origin = sfrag.origin = _org;
+       sfrag.move_velocity = _vel;
+       sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity);
+       sfrag.angles = self.move_angles = _ang;
+
+       sfrag.move_time = time;
+       sfrag.damageforcescale = 4;
+
+       sfrag.nextthink = time + 3;
+       sfrag.cnt = time + 2;
+       sfrag.alpha = 1;
+    sfrag.drawmask = MASK_NORMAL;
+}
diff --git a/qcsrc/client/vehicles/all.qh b/qcsrc/client/vehicles/all.qh
new file mode 100644 (file)
index 0000000..f92ab82
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef VEHICLES_ALL_H
+#define VEHICLES_ALL_H
+
+void RaptorCBShellfragDraw();
+void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang);
+void Vehicles_Precache();
+void Net_AuXair2(bool bIsNew);
+void Net_VehicleSetup();
+
+void CSQC_WAKIZASHI_HUD();
+void CSQC_SPIDER_HUD();
+void CSQC_RAPTOR_HUD();
+void CSQC_BUMBLE_HUD();
+void CSQC_BUMBLE_GUN_HUD();
+
+#endif
diff --git a/qcsrc/client/vehicles/vehicles.qc b/qcsrc/client/vehicles/vehicles.qc
deleted file mode 100644 (file)
index 1582ecf..0000000
+++ /dev/null
@@ -1,1054 +0,0 @@
-#include "vehicles.qh"
-#include "../_all.qh"
-
-#include "../movetypes.qh"
-#include "../movetypes.qh"
-#include "../prandom.qh"
-#include "../scoreboard.qh"
-#include "../t_items.qh"
-
-#include "../../common/buffs.qh"
-#include "../../common/constants.qh"
-#include "../../common/stats.qh"
-#include "../../common/util.qh"
-
-#include "../../csqcmodellib/cl_model.qh"
-
-.float cnt;
-
-const string hud_bg = "gfx/vehicles/frame.tga";
-const string hud_sh = "gfx/vehicles/vh-shield.tga";
-
-const string hud_hp_bar = "gfx/vehicles/bar_up_left.tga";
-const string hud_hp_ico = "gfx/vehicles/health.tga";
-const string hud_sh_bar = "gfx/vehicles/bar_dwn_left.tga";
-const string hud_sh_ico = "gfx/vehicles/shield.tga";
-
-const string hud_ammo1_bar = "gfx/vehicles/bar_up_right.tga";
-const string hud_ammo1_ico = "gfx/vehicles/bullets.tga";
-const string hud_ammo2_bar = "gfx/vehicles/bar_dwn_right.tga";
-const string hud_ammo2_ico = "gfx/vehicles/rocket.tga";
-const string hud_energy = "gfx/vehicles/energy.tga";
-
-const int SBRM_FIRST = 1;
-const int SBRM_VOLLY = 1;
-const int SBRM_GUIDE = 2;
-const int SBRM_ARTILLERY = 3;
-const int SBRM_LAST = 3;
-
-const int RSM_FIRST = 1;
-const int RSM_BOMB = 1;
-const int RSM_FLARE = 2;
-const int RSM_LAST = 2;
-
-entity dropmark;
-float autocvar_cl_vehicles_hudscale = 0.5;
-float autocvar_cl_vehicles_hudalpha = 0.75;
-
-const string raptor_ico =  "gfx/vehicles/raptor.tga";
-const string raptor_gun =  "gfx/vehicles/raptor_guns.tga";
-const string raptor_bomb = "gfx/vehicles/raptor_bombs.tga";
-const string raptor_drop = "gfx/vehicles/axh-dropcross.tga";
-string raptor_xhair;
-
-
-
-const int MAX_AXH = 4;
-entity AuxiliaryXhairs[MAX_AXH];
-
-entityclass(AuxiliaryXhair);
-class(AuxiliaryXhair) .string axh_image;
-class(AuxiliaryXhair) .float  axh_fadetime;
-class(AuxiliaryXhair) .float  axh_drawflag;
-class(AuxiliaryXhair) .float  axh_scale;
-
-const string bumb_ico =  "gfx/vehicles/bumb.tga";
-const string bumb_lgun =  "gfx/vehicles/bumb_lgun.tga";
-const string bumb_rgun =  "gfx/vehicles/bumb_rgun.tga";
-
-const string bumb_gun_ico =  "gfx/vehicles/bumb_side.tga";
-const string bumb_gun_gun =  "gfx/vehicles/bumb_side_gun.tga";
-
-const string spider_ico =  "gfx/vehicles/sbot.tga";
-const string spider_rkt =  "gfx/vehicles/sbot_rpods.tga";
-const string spider_mgun = "gfx/vehicles/sbot_mguns.tga";
-string spider_xhair; // = "gfx/vehicles/axh-special1.tga";
-
-const string waki_ico = "gfx/vehicles/waki.tga";
-const string waki_eng = "gfx/vehicles/waki_e.tga";
-const string waki_gun = "gfx/vehicles/waki_guns.tga";
-const string waki_rkt = "gfx/vehicles/waki_rockets.tga";
-const string waki_xhair = "gfx/vehicles/axh-special1.tga";
-
-float alarm1time;
-float alarm2time;
-int weapon2mode;
-
-void AuxiliaryXhair_Draw2D()
-{
-    vector loc, psize;
-
-    psize = self.axh_scale * draw_getimagesize(self.axh_image);
-    loc = project_3d_to_2d(self.move_origin) - 0.5 * psize;
-    if (!(loc.z < 0 || loc.x < 0 || loc.y < 0 || loc.x > vid_conwidth || loc.y > vid_conheight))
-    {
-        loc.z = 0;
-        psize.z = 0;
-        drawpic(loc, self.axh_image, psize, self.colormod, self.alpha, self.axh_drawflag);
-    }
-
-    if(time - self.cnt > self.axh_fadetime)
-        self.draw2d = func_null;
-}
-
-void Net_AuXair2(bool bIsNew)
-{
-    int axh_id = bound(0, ReadByte(), MAX_AXH);
-    entity axh                 = AuxiliaryXhairs[axh_id];
-
-    if(axh == world || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
-    {
-        axh                                    = spawn();
-               axh.draw2d                      = func_null;
-               axh.drawmask            = MASK_NORMAL;
-               axh.axh_drawflag        = DRAWFLAG_ADDITIVE;
-               axh.axh_fadetime        = 0.1;
-               axh.axh_image           = "gfx/vehicles/axh-ring.tga";
-               axh.axh_scale           = 1;
-        axh.alpha                      = 1;
-               AuxiliaryXhairs[axh_id] = axh;
-    }
-
-       axh.move_origin_x = ReadCoord();
-       axh.move_origin_y = ReadCoord();
-       axh.move_origin_z = ReadCoord();
-       axh.colormod_x = ReadByte() / 255;
-       axh.colormod_y = ReadByte() / 255;
-       axh.colormod_z = ReadByte() / 255;
-    axh.cnt                    = time;
-    axh.draw2d                 = AuxiliaryXhair_Draw2D;
-}
-
-void Net_VehicleSetup()
-{
-    int hud_id = ReadByte();
-
-    // Weapon update?
-    if(hud_id > HUD_VEHICLE_LAST)
-    {
-        weapon2mode = hud_id - HUD_VEHICLE_LAST;
-        return;
-    }
-
-    // hud_id == 0 means we exited a vehicle, so stop alarm sound/s
-    if(hud_id == 0)
-    {
-        sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-        sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-        return;
-    }
-
-    hud_id  = bound(HUD_VEHICLE_FIRST, hud_id, HUD_VEHICLE_LAST);
-
-    // Init auxiliary crosshairs
-    int i;
-    for(i = 0; i < MAX_AXH; ++i)
-    {
-        entity axh = AuxiliaryXhairs[i];
-        if(axh != world && !wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
-            remove(axh);
-
-        axh                                    = spawn();
-               axh.draw2d                      = func_null;
-               axh.drawmask            = MASK_NORMAL;
-               axh.axh_drawflag        = DRAWFLAG_NORMAL;
-               axh.axh_fadetime        = 0.1;
-               axh.axh_image           = "gfx/vehicles/axh-ring.tga";
-               axh.axh_scale           = 1;
-        axh.alpha                      = 1;
-               AuxiliaryXhairs[i]      = axh;
-    }
-
-    switch(hud_id)
-    {
-        case HUD_SPIDERBOT:
-            // Minigun1
-            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-ring.tga";
-            AuxiliaryXhairs[0].axh_scale   = 0.25;
-            // Minigun2
-            AuxiliaryXhairs[1].axh_image   = "gfx/vehicles/axh-ring.tga";
-            AuxiliaryXhairs[1].axh_scale   = 0.25;
-            // Rocket
-            AuxiliaryXhairs[2].axh_image   = "gfx/vehicles/axh-special1.tga";
-            AuxiliaryXhairs[2].axh_scale   = 0.5;
-            break;
-
-        case HUD_WAKIZASHI:
-            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-bracket.tga";
-            AuxiliaryXhairs[0].axh_scale   = 0.25;
-            break;
-
-        case HUD_RAPTOR:
-            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-special2.tga";
-            AuxiliaryXhairs[0].axh_scale   = 0.5;
-            //AuxiliaryXhair[0].alpha       = 0.5;
-
-            AuxiliaryXhairs[1].axh_image   = "gfx/vehicles/axh-bracket.tga";
-            AuxiliaryXhairs[1].axh_scale   = 0.25;
-            //AuxiliaryXhair[1].alpha       = 0.75;
-            //AuxiliaryXhair[1].axh_drawflag  = DRAWFLAG_NORMAL;
-            break;
-
-        case HUD_BUMBLEBEE:
-            // Raygun-locked
-            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-bracket.tga";
-            AuxiliaryXhairs[0].axh_scale   = 0.5;
-
-            // Gunner1
-            AuxiliaryXhairs[1].axh_image   = "gfx/vehicles/axh-target.tga";
-            AuxiliaryXhairs[1].axh_scale   = 0.75;
-
-            // Gunner2
-            AuxiliaryXhairs[2].axh_image   = "gfx/vehicles/axh-target.tga";
-            AuxiliaryXhairs[2].axh_scale   = 0.75;
-            break;
-        case HUD_BUMBLEBEE_GUN:
-            // Plasma cannons
-            AuxiliaryXhairs[0].axh_image   = "gfx/vehicles/axh-bracket.tga";
-            AuxiliaryXhairs[0].axh_scale   = 0.25;
-            // Raygun
-            AuxiliaryXhairs[1].axh_image   = "gfx/vehicles/axh-bracket.tga";
-            AuxiliaryXhairs[1].axh_scale   = 0.25;
-            break;
-    }
-}
-#define HUD_GETSTATS \
-    int vh_health       = getstati(STAT_VEHICLESTAT_HEALTH);  \
-       float shield        = getstati(STAT_VEHICLESTAT_SHIELD);  \
-       noref int energy    = getstati(STAT_VEHICLESTAT_ENERGY);  \
-       noref float ammo1   = getstati(STAT_VEHICLESTAT_AMMO1);   \
-       noref float reload1 = getstati(STAT_VEHICLESTAT_RELOAD1); \
-       noref int ammo2     = getstati(STAT_VEHICLESTAT_AMMO2);   \
-       noref int reload2   = getstati(STAT_VEHICLESTAT_RELOAD2);
-
-void CSQC_BUMBLE_HUD()
-{
-/*
-    drawpic(hudloc, waki_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_b, picsize, '0 1 0' * health + '1 0 0'  * (1 - health), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_r, picsize, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0'  * (1 - energy), 1, DRAWFLAG_NORMAL);
-*/
-       if(autocvar_r_letterbox)
-        return;
-
-    vector picsize, hudloc = '0 0 0', pic2size, picloc;
-
-    // Fetch health & ammo stats
-       HUD_GETSTATS
-
-    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
-    hudloc.y = vid_conheight - picsize.y;
-    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
-
-    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
-
-    shield  *= 0.01;
-    vh_health  *= 0.01;
-    energy  *= 0.01;
-    reload1 *= 0.01;
-
-    pic2size = draw_getimagesize(bumb_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
-    picloc = picsize * 0.5 - pic2size * 0.5;
-
-    if(vh_health < 0.25)
-        drawpic(hudloc + picloc, bumb_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, bumb_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
-
-    drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
-
-// Health bar
-    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
-    if(vh_health < 0.25)
-    {
-        if(alarm1time < time)
-        {
-            alarm1time = time + 2;
-            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm1time)
-        {
-            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm1time = 0;
-        }
-    }
-
-// Shield bar
-    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
-    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
-    if(shield < 0.25)
-    {
-        if(alarm2time < time)
-        {
-            alarm2time = time + 1;
-            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm2time)
-        {
-            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm2time = 0;
-        }
-    }
-
-       ammo1 *= 0.01;
-       ammo2 *= 0.01;
-
-// Gunner1 bar
-    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * ammo1, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-
-// Right gunner slot occupied?
-       if(!AuxiliaryXhairs[1].draw2d)
-       {
-               shield = (picsize.x * 0.5) - (0.5 * stringwidth(_("No right gunner!"), false, '1 0 0' * picsize.y + '0 1 0' * picsize.y));
-               drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL);
-               drawstring(hudloc + picloc + '1 0 0' * shield, _("No right gunner!"), '1 0 0' * picsize.y + '0 1 0' * picsize.y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL);
-       }
-
-// ..  and icon
-    picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
-    if(ammo1 < 0.2)
-        drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-// Gunner2 bar
-    picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * ammo2, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// Left gunner slot occupied?
-       if(!AuxiliaryXhairs[2].draw2d)
-       {
-               shield = (picsize.x * 0.5) - (0.5 * stringwidth(_("No left gunner!"), false, '1 0 0' * picsize.y + '0 1 0' * picsize.y));
-               drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL);
-               drawstring(hudloc + picloc + '1 0 0' * shield, _("No left gunner!"), '1 0 0' * picsize.y + '0 1 0' * picsize.y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL);
-       }
-
-// ..  and icon
-    picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
-    if(ammo2 < 0.2)
-        drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-       if (scoreboard_showscores)
-               HUD_DrawScoreboard();
-    else
-    {
-        picsize = draw_getimagesize(waki_xhair);
-        picsize.x *= 0.5;
-        picsize.y *= 0.5;
-        drawpic('0.5 0 0' * (vid_conwidth - picsize.x) + '0 0.5 0' * (vid_conheight - picsize.y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    }
-
-}
-
-void CSQC_BUMBLE_GUN_HUD()
-{
-
-       if(autocvar_r_letterbox)
-        return;
-
-    vector picsize, hudloc = '0 0 0', pic2size, picloc;
-
-    // Fetch health & ammo stats
-       HUD_GETSTATS
-
-    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
-    hudloc.y = vid_conheight - picsize.y;
-    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
-
-    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
-
-    shield  *= 0.01;
-    vh_health  *= 0.01;
-    energy  *= 0.01;
-    reload1 *= 0.01;
-
-    pic2size = draw_getimagesize(bumb_gun_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
-    picloc = picsize * 0.5 - pic2size * 0.5;
-
-    if(vh_health < 0.25)
-        drawpic(hudloc + picloc, bumb_gun_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, bumb_gun_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
-
-    drawpic(hudloc + picloc, bumb_gun_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
-
-// Health bar
-    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
-    if(vh_health < 0.25)
-    {
-        if(alarm1time < time)
-        {
-            alarm1time = time + 2;
-            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm1time)
-        {
-            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm1time = 0;
-        }
-    }
-
-// Shield bar
-    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
-    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
-    if(shield < 0.25)
-    {
-        if(alarm2time < time)
-        {
-            alarm2time = time + 1;
-            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm2time)
-        {
-            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm2time = 0;
-        }
-    }
-
-// Gun bar
-    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * energy, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-
-// ..  and icon
-    picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
-    if(energy < 0.2)
-        drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-       if (scoreboard_showscores)
-               HUD_DrawScoreboard();
-    /*
-    else
-    {
-        picsize = draw_getimagesize(waki_xhair);
-        picsize_x *= 0.5;
-        picsize_y *= 0.5;
-
-
-        drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    }
-    */
-}
-
-
-
-void CSQC_SPIDER_HUD()
-{
-       if(autocvar_r_letterbox)
-        return;
-
-    vector picsize, hudloc = '0 0 0', pic2size, picloc;
-    int i;
-
-    // Fetch health & ammo stats
-       HUD_GETSTATS
-
-    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
-    hudloc.y = vid_conheight - picsize.y;
-    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
-
-    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
-
-    ammo1   *= 0.01;
-    shield  *= 0.01;
-    vh_health  *= 0.01;
-    reload2 *= 0.01;
-
-    pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
-    picloc = picsize * 0.5 - pic2size * 0.5;
-    if(vh_health < 0.25)
-        drawpic(hudloc + picloc, spider_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, spider_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, spider_rkt, pic2size,  '1 1 1' * reload2 + '1 0 0' * (1 - reload2), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, spider_mgun, pic2size, '1 1 1' * ammo1   + '1 0 0' * (1 - ammo1),   1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
-
-// Health bar
-    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
-    if(vh_health < 0.25)
-    {
-        if(alarm1time < time)
-        {
-            alarm1time = time + 2;
-            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm1time)
-        {
-            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm1time = 0;
-        }
-    }
-// Shield bar
-    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
-    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
-    if(shield < 0.25)
-    {
-        if(alarm2time < time)
-        {
-            alarm2time = time + 1;
-            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm2time)
-        {
-            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm2time = 0;
-        }
-    }
-
-// Minigun bar
-    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * ammo1, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
-    if(ammo1 < 0.2)
-        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-// Rocket ammo bar
-    picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
-    ammo1 = picsize.x / 8;
-    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, hudloc.y + picloc.y, picsize.x * reload2, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-
-// ..  and icons
-    pic2size = 0.35 * draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
-    picloc.x -= pic2size.x;
-    picloc.y += pic2size.y * 2.25;
-    if(ammo2 == 9)
-    {
-        for(i = 1; i < 9; ++i)
-        {
-            picloc.x += ammo1;
-            drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((8 * reload2 <= i) ? '0 0 0' : '1 1 1'), 0.75, DRAWFLAG_NORMAL);
-        }
-    }
-    else
-    {
-        for(i = 1; i < 9; ++i)
-        {
-            picloc.x += ammo1;
-            drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((i >= ammo2) ? '1 1 1' : '0 0 0'), 0.75, DRAWFLAG_NORMAL);
-        }
-    }
-    pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
-    if(ammo2 == 9)
-        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-       if (scoreboard_showscores)
-               HUD_DrawScoreboard();
-    else
-    {
-        switch(weapon2mode)
-        {
-            case SBRM_VOLLY:
-                spider_xhair = "gfx/vehicles/axh-bracket.tga";
-                break;
-            case SBRM_GUIDE:
-                spider_xhair = "gfx/vehicles/axh-cross.tga";
-                break;
-            case SBRM_ARTILLERY:
-                spider_xhair = "gfx/vehicles/axh-tag.tga";
-                break;
-            default:
-                spider_xhair= "gfx/vehicles/axh-tag.tga";
-        }
-
-        picsize = draw_getimagesize(spider_xhair);
-        picsize.x *= autocvar_cl_vehicle_spiderbot_cross_size;
-        picsize.y *= autocvar_cl_vehicle_spiderbot_cross_size;
-
-        drawpic('0.5 0 0' * (vid_conwidth - picsize.x) + '0 0.5 0' * (vid_conheight - picsize.y), spider_xhair, picsize, '1 1 1', autocvar_cl_vehicle_spiderbot_cross_alpha, DRAWFLAG_ADDITIVE);
-    }
-}
-
-void CSQC_RAPTOR_HUD()
-{
-       if(autocvar_r_letterbox)
-        return;
-
-    vector picsize, hudloc = '0 0 0', pic2size, picloc;
-
-    // Fetch health & ammo stats
-       HUD_GETSTATS
-
-    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
-    hudloc.y = vid_conheight - picsize.y;
-    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
-
-    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
-
-    ammo1   *= 0.01;
-    ammo2   *= 0.01;
-    shield  *= 0.01;
-    vh_health  *= 0.01;
-    energy  *= 0.01;
-    reload1 = reload2 * 0.01;
-    //reload2 *= 0.01;
-
-    pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
-    picloc = picsize * 0.5 - pic2size * 0.5;
-    if(vh_health < 0.25)
-        drawpic(hudloc + picloc, raptor_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, raptor_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, raptor_bomb, pic2size,  '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, raptor_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
-
-// Health bar
-    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
-    if(vh_health < 0.25)
-    {
-        if(alarm1time < time)
-        {
-            alarm1time = time + 2;
-            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm1time)
-        {
-            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm1time = 0;
-        }
-    }
-
-// Shield bar
-    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
-    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
-    if(shield < 0.25)
-    {
-        if(alarm2time < time)
-        {
-            alarm2time = time + 1;
-            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm2time)
-        {
-            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm2time = 0;
-        }
-    }
-
-// Gun bar
-    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * energy, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
-    if(energy < 0.2)
-        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-// Bomb bar
-    picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, hudloc.y + picloc.y, picsize.x * reload1, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
-    if(reload1 != 1)
-        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-    if(weapon2mode == RSM_FLARE)
-    {
-        raptor_xhair =  "gfx/vehicles/axh-bracket.tga";
-    }
-    else
-    {
-        raptor_xhair =  "gfx/vehicles/axh-ring.tga";
-
-        // Bombing crosshair
-        if(!dropmark)
-        {
-            dropmark = spawn();
-            dropmark.owner = self;
-            dropmark.gravity = 1;
-        }
-
-        if(reload2 == 100)
-        {
-            vector where;
-
-            setorigin(dropmark, pmove_org);
-            dropmark.velocity = pmove_vel;
-            tracetoss(dropmark, self);
-
-            where = project_3d_to_2d(trace_endpos);
-
-            setorigin(dropmark, trace_endpos);
-            picsize = draw_getimagesize(raptor_drop) * 0.2;
-
-            if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight))
-            {
-                where.x -= picsize.x * 0.5;
-                where.y -= picsize.y * 0.5;
-                where.z = 0;
-                drawpic(where, raptor_drop, picsize, '0 2 0', 1, DRAWFLAG_ADDITIVE);
-            }
-            dropmark.cnt = time + 5;
-        }
-        else
-        {
-            vector where;
-            if(dropmark.cnt > time)
-            {
-                where = project_3d_to_2d(dropmark.origin);
-                picsize = draw_getimagesize(raptor_drop) * 0.25;
-
-                if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight))
-                {
-                    where.x -= picsize.x * 0.5;
-                    where.y -= picsize.y * 0.5;
-                    where.z = 0;
-                    drawpic(where, raptor_drop, picsize, '2 0 0', 1, DRAWFLAG_ADDITIVE);
-                }
-            }
-        }
-    }
-
-       if (scoreboard_showscores)
-               HUD_DrawScoreboard();
-    else
-    {
-        picsize = draw_getimagesize(raptor_xhair);
-        picsize.x *= 0.5;
-        picsize.y *= 0.5;
-
-        drawpic('0.5 0 0' * (vid_conwidth - picsize.x) + '0 0.5 0' * (vid_conheight - picsize.y), raptor_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    }
-}
-
-void CSQC_WAKIZASHI_HUD()
-{
-/*
-    drawpic(hudloc, waki_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_b, picsize, '0 1 0' * health + '1 0 0'  * (1 - health), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_r, picsize, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0'  * (1 - energy), 1, DRAWFLAG_NORMAL);
-*/
-       if(autocvar_r_letterbox)
-        return;
-
-    vector picsize, hudloc = '0 0 0', pic2size, picloc;
-
-    // Fetch health & ammo stats
-       HUD_GETSTATS
-
-    picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
-    hudloc.y = vid_conheight - picsize.y;
-    hudloc.x = vid_conwidth * 0.5 - picsize.x * 0.5;
-
-    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
-
-    shield  *= 0.01;
-    vh_health  *= 0.01;
-    energy  *= 0.01;
-    reload1 *= 0.01;
-
-    pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
-    picloc = picsize * 0.5 - pic2size * 0.5;
-    if(vh_health < 0.25)
-        drawpic(hudloc + picloc, waki_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, waki_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, waki_eng, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, waki_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, waki_rkt, pic2size,  '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
-
-// Health bar
-    picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
-    if(vh_health < 0.25)
-    {
-        if(alarm1time < time)
-        {
-            alarm1time = time + 2;
-            sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm1time)
-        {
-            sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm1time = 0;
-        }
-    }
-
-
-// Shield bar
-    picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x + (picsize.x * (1 - shield)), 0, vid_conwidth, vid_conheight);
-    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
-    picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
-    if(shield < 0.25)
-    {
-        if(alarm2time < time)
-        {
-            alarm2time = time + 1;
-            sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
-        }
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        if(alarm2time)
-        {
-            sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
-            alarm2time = 0;
-        }
-    }
-
-// Gun bar
-    picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, picloc.y, picsize.x * energy, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
-    if(energy < 0.2)
-        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-// Bomb bar
-    picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
-    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
-    drawsetcliparea(hudloc.x + picloc.x, hudloc.y + picloc.y, picsize.x * reload1, vid_conheight);
-    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    drawresetcliparea();
-// ..  and icon
-    pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
-    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
-    if(reload1 != 1)
-        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-    else
-        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-       if (scoreboard_showscores)
-               HUD_DrawScoreboard();
-    else
-    {
-        picsize = draw_getimagesize(waki_xhair);
-        picsize.x *= 0.5;
-        picsize.y *= 0.5;
-
-
-        drawpic('0.5 0 0' * (vid_conwidth - picsize.x) + '0 0.5 0' * (vid_conheight - picsize.y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    }
-}
-
-void Vehicles_Precache()
-{
-       precache_model("models/vehicles/bomblet.md3");
-       precache_model("models/vehicles/clusterbomb.md3");
-       precache_model("models/vehicles/clusterbomb_fragment.md3");
-       precache_model("models/vehicles/rocket01.md3");
-       precache_model("models/vehicles/rocket02.md3");
-
-       precache_sound ("vehicles/alarm.wav");
-       precache_sound ("vehicles/alarm_shield.wav");
-}
-
-void RaptorCBShellfragDraw()
-{
-       if(wasfreed(self))
-               return;
-
-       Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
-       self.move_avelocity += randomvec() * 15;
-       self.renderflags = 0;
-
-       if(self.cnt < time)
-               self.alpha = bound(0, self.nextthink - time, 1);
-
-       if(self.alpha < ALPHA_MIN_VISIBLE)
-        remove(self);
-}
-
-void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
-{
-    entity sfrag;
-
-    sfrag = spawn();
-    setmodel(sfrag, "models/vehicles/clusterbomb_fragment.md3");
-    setorigin(sfrag, _org);
-
-       sfrag.move_movetype = MOVETYPE_BOUNCE;
-       sfrag.gravity = 0.15;
-       sfrag.solid = SOLID_CORPSE;
-
-       sfrag.draw = RaptorCBShellfragDraw;
-
-       sfrag.move_origin = sfrag.origin = _org;
-       sfrag.move_velocity = _vel;
-       sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity);
-       sfrag.angles = self.move_angles = _ang;
-
-       sfrag.move_time = time;
-       sfrag.damageforcescale = 4;
-
-       sfrag.nextthink = time + 3;
-       sfrag.cnt = time + 2;
-       sfrag.alpha = 1;
-    sfrag.drawmask = MASK_NORMAL;
-}
diff --git a/qcsrc/client/vehicles/vehicles.qh b/qcsrc/client/vehicles/vehicles.qh
deleted file mode 100644 (file)
index e8d3ddb..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef VEHICLES_H
-#define VEHICLES_H
-
-void RaptorCBShellfragDraw();
-void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang);
-void Vehicles_Precache();
-void Net_AuXair2(bool bIsNew);
-void Net_VehicleSetup();
-
-void CSQC_WAKIZASHI_HUD();
-void CSQC_SPIDER_HUD();
-void CSQC_RAPTOR_HUD();
-void CSQC_BUMBLE_HUD();
-void CSQC_BUMBLE_GUN_HUD();
-
-#endif
index 3ffb406..d3bcf92 100644 (file)
@@ -9,7 +9,7 @@
 #include "scoreboard.qh"
 #include "shownames.qh"
 #include "target_music.qh"
-#include "vehicles/vehicles.qh"
+#include "vehicles/all.qh"
 #include "waypointsprites.qh"
 
 #include "../common/constants.qh"
@@ -19,7 +19,7 @@
 #include "../common/teams.qh"
 #include "../common/util.qh"
 
-#include "../common/weapons/weapons.qh"
+#include "../common/weapons/all.qh"
 
 #include "../csqcmodellib/cl_player.qh"
 
index dc38219..aed0865 100644 (file)
@@ -8,7 +8,7 @@
 #include "../common/constants.qh"
 #include "../common/teams.qh"
 
-#include "../common/weapons/weapons.qh"
+#include "../common/weapons/all.qh"
 
 #include "../csqcmodellib/interpolate.qh"
 
diff --git a/qcsrc/common/command/all.qc b/qcsrc/common/command/all.qc
new file mode 100644 (file)
index 0000000..dc1c044
--- /dev/null
@@ -0,0 +1,3 @@
+#include "generic.qc"
+#include "markup.qc"
+#include "rpn.qc"
diff --git a/qcsrc/common/command/all.qh b/qcsrc/common/command/all.qh
new file mode 100644 (file)
index 0000000..7eeb5c3
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef COMMON_COMMANDS_ALL_H
+#define COMMON_COMMANDS_ALL_H
+
+#include "generic.qh"
+#include "markup.qh"
+#include "rpn.qh"
+
+#endif
diff --git a/qcsrc/common/command/commands.qc b/qcsrc/common/command/commands.qc
deleted file mode 100644 (file)
index dc1c044..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "generic.qc"
-#include "markup.qc"
-#include "rpn.qc"
diff --git a/qcsrc/common/command/commands.qh b/qcsrc/common/command/commands.qh
deleted file mode 100644 (file)
index d434a86..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef COMMON_COMMANDS_H
-#define COMMON_COMMANDS_H
-
-#include "generic.qh"
-#include "markup.qh"
-#include "rpn.qh"
-
-#endif
index f0b6d0d..6aa93a0 100644 (file)
@@ -241,6 +241,25 @@ void GenericCommand_dumpcommands(float request)
        }
 }
 
+void GenericCommand_dumpitems(float request)
+{
+       switch(request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       Dump_Items();
+                       return;
+               }
+
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       printf("\nUsage:^3 %s dumpitems", GetProgramCommandPrefix());
+                       return;
+               }
+       }
+}
+
 void GenericCommand_dumpnotifs(float request)
 {
        switch(request)
@@ -651,6 +670,7 @@ void GenericCommand_(float request)
 #define GENERIC_COMMANDS(request,arguments,command) \
        GENERIC_COMMAND("addtolist", GenericCommand_addtolist(request, arguments), "Add a string to a cvar") \
        GENERIC_COMMAND("dumpcommands", GenericCommand_dumpcommands(request), "Dump all commands on the program to *_cmd_dump.txt") \
+       GENERIC_COMMAND("dumpitems", GenericCommand_dumpitems(request), "Dump all items to the console") \
        GENERIC_COMMAND("dumpnotifs", GenericCommand_dumpnotifs(request), "Dump all notifications into notifications_dump.txt") \
        GENERIC_COMMAND("dumpweapons", GenericCommand_dumpweapons(request), "Dump all weapons into weapons_dump.txt") \
        GENERIC_COMMAND("maplist", GenericCommand_maplist(request, arguments), "Automatic control of maplist") \
index 45a65ab..8c7cb6b 100644 (file)
@@ -64,6 +64,7 @@ const int ENT_CLIENT_WARPZONE = 24;
 const int ENT_CLIENT_WARPZONE_CAMERA = 25;
 const int ENT_CLIENT_TRIGGER_MUSIC = 26;
 const int ENT_CLIENT_HOOK = 27;
+const int ENT_CLIENT_INVENTORY = 28;
 const int ENT_CLIENT_ARC_BEAM = 29; // WEAPONTODO: fix numbers
 const int ENT_CLIENT_ACCURACY = 30;
 const int ENT_CLIENT_SHOWNAMES = 31;
diff --git a/qcsrc/common/items/all.inc b/qcsrc/common/items/all.inc
new file mode 100644 (file)
index 0000000..2c4f1de
--- /dev/null
@@ -0,0 +1,7 @@
+#include "item/ammo.qc"
+#include "item/armor.qc"
+#include "item/buff.qc"
+#include "item/health.qc"
+#include "item/jetpack.qc"
+#include "item/pickup.qc"
+#include "item/powerup.qc"
diff --git a/qcsrc/common/items/all.qc b/qcsrc/common/items/all.qc
new file mode 100644 (file)
index 0000000..fa198bb
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef ALL_C
+#define ALL_C
+#include "all.qh"
+
+#include "all.inc"
+
+void Dump_Items()
+{
+    ITEMS_FOREACH(true, LAMBDA({
+        ITEM_HANDLE(Show, it);
+    }));
+}
+
+#endif
diff --git a/qcsrc/common/items/all.qh b/qcsrc/common/items/all.qh
new file mode 100644 (file)
index 0000000..1786b42
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef ALL_H
+#define ALL_H
+
+const int MAX_ITEMS = 24;
+entity ITEMS[MAX_ITEMS];
+
+#define ITEMS_FOREACH(pred, body) do {      \
+    for (int i = 0; i < ITEM_COUNT; i++) {  \
+        const noref entity it = ITEMS[i];   \
+        if (pred) { body }                  \
+    }                                       \
+} while(0)
+
+void RegisterItems();
+void Dump_Items();
+
+#endif
+
+#include "inventory.qh"
diff --git a/qcsrc/common/items/inventory.qh b/qcsrc/common/items/inventory.qh
new file mode 100644 (file)
index 0000000..89abc97
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef INVENTORY_H
+#define INVENTORY_H
+
+#include "all.qh"
+#include "item/pickup.qh"
+
+entityclass(Inventory);
+/** Stores counts of items, the id being the index */
+class(Inventory) .int inv_items[MAX_ITEMS];
+
+/** Player inventory; Inventories also have one inventory for storing the previous state */
+.Inventory inventory;
+
+#ifdef CSQC
+void Inventory_Read(Inventory data)
+{
+    const int bits = ReadInt24_t();
+    ITEMS_FOREACH(bits & BIT(i), LAMBDA({
+        .int fld = inv_items[i];
+        int prev = data.(fld);
+        int next = data.(fld) = ReadByte();
+        dprintf("%s: %.0f -> %.0f\n", ITEMS[i].m_name, prev, next);
+    }));
+}
+#endif
+
+#ifdef SVQC
+void Inventory_Write(Inventory data)
+{
+    int bits = 0;
+    ITEMS_FOREACH(true, LAMBDA({
+        .int fld = inv_items[i];
+        bits = BITSET(bits, BIT(i), data.inventory.(fld) != (data.inventory.(fld) = data.(fld)));
+    }));
+    WriteInt24_t(MSG_ENTITY, bits);
+    ITEMS_FOREACH(bits & BIT(i), LAMBDA({
+        WriteByte(MSG_ENTITY, data.inv_items[i]);
+    }));
+}
+#endif
+
+#ifdef SVQC
+bool Inventory_Send(entity to, int sf)
+{
+    WriteByte(MSG_ENTITY, ENT_CLIENT_INVENTORY);
+    entity e = self.owner;
+    if (IS_SPEC(e)) e = e.enemy;
+    Inventory data = e.inventory;
+    Inventory_Write(data);
+    return true;
+}
+
+void Inventory_new(entity e)
+{
+    Inventory inv = new(Inventory), bak = new(Inventory);
+    inv.classname = "inventory", bak.classname = "inventory";
+    inv.inventory = bak;
+    inv.drawonlytoclient = e;
+    Net_LinkEntity((inv.owner = e).inventory = inv, false, 0, Inventory_Send);
+}
+void Inventory_delete(entity e) { remove(e.inventory.inventory); remove(e.inventory); }
+void Inventory_update(entity e) { e.inventory.SendFlags = 0xFFFFFF; }
+#endif
+
+#endif
diff --git a/qcsrc/common/items/item.qh b/qcsrc/common/items/item.qh
new file mode 100644 (file)
index 0000000..da4e7a4
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef GAMEITEM_H
+#define GAMEITEM_H
+#include "../oo.qh"
+#define ITEM_HANDLE(signal, ...) __Item_Send_##signal(__VA_ARGS__)
+CLASS(GameItem, Object)
+    ATTRIB(GameItem, m_id, int, 0)
+    METHOD(GameItem, show, void(entity this))
+    void GameItem_show(entity this) { print("A game item\n"); }
+    void ITEM_HANDLE(Show, entity this) { this.show(this); }
+ENDCLASS(GameItem)
+
+
+int ITEM_COUNT;
+#define REGISTER_ITEM(id, class, body)          \
+    entity ITEM_##id;                           \
+    void RegisterItems_##id() {                 \
+        const entity this = NEW(class);         \
+        ITEM_##id = this;                       \
+        this.m_id = ITEM_COUNT;                 \
+        ITEMS[ITEM_COUNT++] = this;             \
+        body                                    \
+    }                                           \
+    ACCUMULATE_FUNCTION(RegisterItems, RegisterItems_##id)
+
+#endif
diff --git a/qcsrc/common/items/item/ammo.qc b/qcsrc/common/items/item/ammo.qc
new file mode 100644 (file)
index 0000000..032fcc3
--- /dev/null
@@ -0,0 +1,70 @@
+#include "ammo.qh"
+#ifdef SVQC
+    #include "../../../server/t_items.qh"
+#endif
+
+#define WITH(it) this.m_##it;
+#define CONFIGURE(...) MAP(WITH, __VA_ARGS__)
+#define DEFINE(id, ...)                                                 \
+    REGISTER_ITEM(id, Ammo, LAMBDA(                                     \
+        IF(SV, CONFIGURE                                                \
+        ,   respawntime         =       GET(g_pickup_respawntime_ammo)  \
+        ,   respawntimejitter   = GET(g_pickup_respawntimejitter_ammo)  \
+        )                                                               \
+        UNWORDS(__VA_ARGS__)                                            \
+    ))
+
+DEFINE(Bullets
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/a_bullets.mdl"
+    ,   name                =   "bullets"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   2000
+    ,   itemid              =   IT_NAILS
+    )
+)
+DEFINE(Cells
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/a_cells.md3"
+    ,   name                =   "cells"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   2000
+    ,   itemid              =   IT_CELLS
+    )
+)
+DEFINE(Plasma
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/a_cells.md3"
+    ,   name                =   "plasma"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   2000
+    ,   itemid              =   IT_PLASMA
+    )
+)
+DEFINE(Rockets
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/a_rockets.md3"
+    ,   name                =   "rockets"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   3000
+    ,   itemid              =   IT_ROCKETS
+    )
+)
+DEFINE(Shells
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/a_shells.md3"
+    ,   name                =   "shells"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   500
+    ,   itemid              =   IT_SHELLS
+    )
+)
+
+#undef WITH
+#undef CONFIGURE
+#undef DEFINE
diff --git a/qcsrc/common/items/item/ammo.qh b/qcsrc/common/items/item/ammo.qh
new file mode 100644 (file)
index 0000000..41e2ac8
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef AMMO_H
+#define AMMO_H
+#include "pickup.qh"
+CLASS(Ammo, Pickup)
+#ifdef SVQC
+    ATTRIB(Ammo, m_pickupevalfunc, float(entity player, entity item), commodity_pickupevalfunc)
+#endif
+ENDCLASS(Ammo)
+#endif
diff --git a/qcsrc/common/items/item/armor.qc b/qcsrc/common/items/item/armor.qc
new file mode 100644 (file)
index 0000000..8fed098
--- /dev/null
@@ -0,0 +1,68 @@
+#include "armor.qh"
+#ifdef SVQC
+    #include "../../../server/t_items.qh"
+#endif
+
+#define WITH(it) this.m_##it;
+#define CONFIGURE(...) MAP(WITH, __VA_ARGS__)
+#define DEFINE(id, ...) REGISTER_ITEM(id, Armor, UNWORDS(__VA_ARGS__))
+
+DEFINE(ArmorSmall
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/item_armor_small.md3"
+    ,   sound               =   "misc/armor1.wav"
+    ,   name                =   "5 Armor"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_LOW
+    ,   itemid              =   IT_ARMOR_SHARD
+    ,   respawntime         =         GET(g_pickup_respawntime_short)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_short)
+    )
+)
+
+DEFINE(ArmorMedium
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/item_armor_medium.md3"
+    ,   sound               =   "misc/armor10.wav"
+    ,   name                =   "25 Armor"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_MID
+    ,   itemid              =   IT_ARMOR
+    ,   respawntime         =         GET(g_pickup_respawntime_medium)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_medium)
+    )
+)
+
+DEFINE(ArmorBig
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/item_armor_big.md3"
+    ,   sound               =   "misc/armor17_5.wav"
+    ,   name                =   "50 Armor"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   20000 // FIXME: higher than BOT_PICKUP_RATING_HIGH?
+    ,   itemid              =   IT_ARMOR
+    ,   respawntime         =         GET(g_pickup_respawntime_long)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_long)
+    )
+)
+
+DEFINE(ArmorLarge
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/item_armor_large.md3"
+    ,   sound               =   "misc/armor25.wav"
+    ,   name                =   "100 Armor"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_HIGH
+    ,   itemid              =   IT_ARMOR
+    ,   respawntime         =         GET(g_pickup_respawntime_long)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_long)
+    )
+)
+
+#undef WITH
+#undef CONFIGURE
+#undef DEFINE
diff --git a/qcsrc/common/items/item/armor.qh b/qcsrc/common/items/item/armor.qh
new file mode 100644 (file)
index 0000000..48a80f8
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef ARMOR_H
+#define ARMOR_H
+#include "pickup.qh"
+CLASS(Armor, Pickup)
+#ifdef SVQC
+    ATTRIB(Armor, m_pickupevalfunc, float(entity player, entity item), commodity_pickupevalfunc)
+#endif
+ENDCLASS(Armor)
+#endif
diff --git a/qcsrc/common/items/item/buff.qc b/qcsrc/common/items/item/buff.qc
new file mode 100644 (file)
index 0000000..d9420d1
--- /dev/null
@@ -0,0 +1,3 @@
+#include "buff.qh"
+
+REGISTER_ITEM(DefaultBuff, Buff, LAMBDA())
diff --git a/qcsrc/common/items/item/buff.qh b/qcsrc/common/items/item/buff.qh
new file mode 100644 (file)
index 0000000..4ad93cb
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef BUFF_H
+#define BUFF_H
+#include "pickup.qh"
+CLASS(Buff, Pickup)
+    ATTRIB(Buff, m_name, string, "Buff")
+ENDCLASS(Buff)
+#endif
diff --git a/qcsrc/common/items/item/health.qc b/qcsrc/common/items/item/health.qc
new file mode 100644 (file)
index 0000000..08b422d
--- /dev/null
@@ -0,0 +1,68 @@
+#include "health.qh"
+#ifdef SVQC
+    #include "../../../server/t_items.qh"
+#endif
+
+#define WITH(it) this.m_##it;
+#define CONFIGURE(...) MAP(WITH, __VA_ARGS__)
+#define DEFINE(id, ...) REGISTER_ITEM(id, Health, UNWORDS(__VA_ARGS__))
+
+DEFINE(HealthSmall
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_h1.md3"
+    ,   sound               =   "misc/minihealth.wav"
+    ,   name                =   "5 Health"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_LOW
+    ,   itemid              =   IT_5HP
+    ,   respawntime         =         GET(g_pickup_respawntime_short)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_short)
+    )
+)
+
+DEFINE(HealthMedium
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_h25.md3"
+    ,   sound               =   "misc/mediumhealth.wav"
+    ,   name                =   "25 Health"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_MID
+    ,   itemid              =   IT_25HP
+    ,   respawntime         =         GET(g_pickup_respawntime_short)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_short)
+    )
+)
+
+DEFINE(HealthLarge
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_h50.md3"
+    ,   sound               =   "misc/mediumhealth.wav"
+    ,   name                =   "50 Health"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_MID
+    ,   itemid              =   IT_25HP
+    ,   respawntime         =         GET(g_pickup_respawntime_medium)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_medium)
+    )
+)
+
+DEFINE(HealthMega
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_h100.md3"
+    ,   sound               =   "misc/megahealth.wav"
+    ,   name                =   "100 Health"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_HIGH
+    ,   itemid              =   IT_HEALTH
+    ,   respawntime         =         GET(g_pickup_respawntime_long)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_long)
+    )
+)
+
+#undef WITH
+#undef CONFIGURE
+#undef DEFINE
diff --git a/qcsrc/common/items/item/health.qh b/qcsrc/common/items/item/health.qh
new file mode 100644 (file)
index 0000000..15f1f8d
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef HEALTH_H
+#define HEALTH_H
+#include "pickup.qh"
+CLASS(Health, Pickup)
+#ifdef SVQC
+    ATTRIB(Health, m_pickupevalfunc, float(entity player, entity item), commodity_pickupevalfunc)
+#endif
+ENDCLASS(Health)
+#endif
diff --git a/qcsrc/common/items/item/jetpack.qc b/qcsrc/common/items/item/jetpack.qc
new file mode 100644 (file)
index 0000000..9ff4ed0
--- /dev/null
@@ -0,0 +1,56 @@
+#ifdef SVQC
+    #include "../../../server/t_items.qh"
+    #include "../../../server/constants.qh"
+#endif
+
+#define WITH(it) this.m_##it;
+#define CONFIGURE(...) MAP(WITH, __VA_ARGS__)
+#define DEFINE(id, ...) REGISTER_ITEM(id, Pickup, UNWORDS(__VA_ARGS__))
+
+DEFINE(Jetpack
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_jetpack.md3"
+    ,   name                =   "Jet pack"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_LOW
+    ,   itemflags           =   FL_POWERUP
+    ,   itemid              =   IT_JETPACK
+    ,   pickupevalfunc      =   commodity_pickupevalfunc
+    ,   respawntime         =         GET(g_pickup_respawntime_powerup)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_powerup)
+    )
+)
+
+DEFINE(JetpackFuel
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_fuel.md3"
+    ,   name                =   "Fuel"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_LOW
+    ,   itemid              =   IT_FUEL
+    ,   pickupevalfunc      =   commodity_pickupevalfunc
+    ,   respawntime         =         GET(g_pickup_respawntime_ammo)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_ammo)
+    )
+)
+
+DEFINE(JetpackRegen
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_fuelregen.md3"
+    ,   name                =   "Fuel regenerator"
+    )
+    ,IF(SV, CONFIGURE
+    ,   botvalue            =   BOT_PICKUP_RATING_LOW
+    ,   itemflags           =   FL_POWERUP
+    ,   itemid              =   IT_FUEL_REGEN
+    ,   pickupevalfunc      =   commodity_pickupevalfunc
+    ,   respawntime         =         GET(g_pickup_respawntime_powerup)
+    ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_powerup)
+    )
+)
+
+#undef WITH
+#undef CONFIGURE
+#undef DEFINE
diff --git a/qcsrc/common/items/item/pickup.qc b/qcsrc/common/items/item/pickup.qc
new file mode 100644 (file)
index 0000000..35aac2b
--- /dev/null
@@ -0,0 +1,13 @@
+#include "pickup.qh"
+
+#ifdef SVQC
+bool ITEM_HANDLE(Pickup, entity this, entity item, entity player) {
+    bool b = this.giveTo(this, item, player);
+    if (b) {
+        dprintf("entity %i picked up %s\n", player, this.m_name);
+        player.inventory.inv_items[this.m_id]++;
+        Inventory_update(player);
+    }
+    return b;
+}
+#endif
diff --git a/qcsrc/common/items/item/pickup.qh b/qcsrc/common/items/item/pickup.qh
new file mode 100644 (file)
index 0000000..1875517
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef PICKUP_H
+#define PICKUP_H
+#include "../item.qh"
+CLASS(Pickup, GameItem)
+    ATTRIB(Pickup, m_model, string, string_null)
+    ATTRIB(Pickup, m_sound, string, "misc/itempickup.wav")
+    ATTRIB(Pickup, m_name, string, string_null)
+    METHOD(Pickup, show, void(entity this))
+    void Pickup_show(entity this) { printf("%s: %s\n", etos(this), this.m_name); }
+#ifdef SVQC
+    ATTRIB(Pickup, m_botvalue, int, 0)
+    ATTRIB(Pickup, m_itemflags, int, 0)
+    ATTRIB(Pickup, m_itemid, int, 0)
+    ATTRIB(Pickup, m_pickupevalfunc, float(entity player, entity item), generic_pickupevalfunc)
+    ATTRIB(Pickup, m_respawntime, float(), func_null)
+    ATTRIB(Pickup, m_respawntimejitter, float(), func_null)
+    METHOD(Pickup, giveTo, bool(entity this, entity item, entity player))
+    bool Pickup_giveTo(entity this, entity item, entity player) { return Item_GiveTo(item, player); }
+    bool ITEM_HANDLE(Pickup, entity this, entity item, entity player);
+#endif
+ENDCLASS(Pickup)
+
+#ifdef SVQC
+// For g_pickup_respawntime
+#include "../../../server/defs.qh"
+// Getters to dynamically retrieve the values of g_pickup_respawntime*
+GETTER(float, g_pickup_respawntime_weapon)
+GETTER(float, g_pickup_respawntime_superweapon)
+GETTER(float, g_pickup_respawntime_ammo)
+GETTER(float, g_pickup_respawntime_short)
+GETTER(float, g_pickup_respawntime_medium)
+GETTER(float, g_pickup_respawntime_long)
+GETTER(float, g_pickup_respawntime_powerup)
+GETTER(float, g_pickup_respawntimejitter_weapon)
+GETTER(float, g_pickup_respawntimejitter_superweapon)
+GETTER(float, g_pickup_respawntimejitter_ammo)
+GETTER(float, g_pickup_respawntimejitter_short)
+GETTER(float, g_pickup_respawntimejitter_medium)
+GETTER(float, g_pickup_respawntimejitter_long)
+GETTER(float, g_pickup_respawntimejitter_powerup)
+
+#endif
+
+#endif
diff --git a/qcsrc/common/items/item/powerup.qc b/qcsrc/common/items/item/powerup.qc
new file mode 100644 (file)
index 0000000..f10a97e
--- /dev/null
@@ -0,0 +1,40 @@
+#include "powerup.qh"
+#include "../../../server/t_items.qh"
+
+#define WITH(it) this.m_##it;
+#define CONFIGURE(...) MAP(WITH, __VA_ARGS__)
+#define DEFINE(id, ...)                                                     \
+    REGISTER_ITEM(id, Ammo, LAMBDA(                                         \
+        IF(SV, CONFIGURE                                                    \
+        ,   botvalue            =   100000                                  \
+        ,   itemflags           =   FL_POWERUP                              \
+        ,   respawntime         =         GET(g_pickup_respawntime_powerup) \
+        ,   respawntimejitter   =   GET(g_pickup_respawntimejitter_powerup) \
+        )                                                                   \
+        UNWORDS(__VA_ARGS__)                                          \
+    ))
+
+DEFINE(Strength
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_strength.md3"
+    ,   sound               =   "misc/powerup.wav"
+    ,   name                =   "Strength Powerup"
+    )
+    ,IF(SV, CONFIGURE
+    ,   itemid              =   IT_STRENGTH
+    )
+)
+DEFINE(Shield
+    ,APPLY(CONFIGURE
+    ,   model               =   "models/items/g_invincible.md3"
+    ,   sound               =   "misc/powerup_shield.wav"
+    ,   name                =   "Shield"
+    )
+    ,IF(SV, CONFIGURE
+    ,   itemid              =   IT_INVINCIBLE
+    )
+)
+
+#undef WITH
+#undef CONFIGURE
+#undef DEFINE
diff --git a/qcsrc/common/items/item/powerup.qh b/qcsrc/common/items/item/powerup.qh
new file mode 100644 (file)
index 0000000..d27c1e6
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef POWERUP_H
+#define POWERUP_H
+#include "pickup.qh"
+CLASS(Powerup, Pickup)
+ENDCLASS(Powerup)
+
+#ifdef SVQC
+// For FL_POWERUP
+#include "../../../server/constants.qh"
+#endif
+
+#endif
index c3f15d1..2e692d7 100644 (file)
@@ -3,7 +3,7 @@
     #include "../client/defs.qh"
     #include "util.qh"
     #include "buffs.qh"
-    #include "weapons/weapons.qh"
+    #include "weapons/all.qh"
     #include "mapinfo.qh"
 #elif defined(MENUQC)
 #elif defined(SVQC)
@@ -11,7 +11,7 @@
     #include "../dpdefs/dpextensions.qh"
     #include "util.qh"
     #include "buffs.qh"
-    #include "monsters/monsters.qh"
+    #include "monsters/all.qh"
     #include "mapinfo.qh"
 #endif
 
diff --git a/qcsrc/common/monsters/all.qc b/qcsrc/common/monsters/all.qc
new file mode 100644 (file)
index 0000000..37dbcb3
--- /dev/null
@@ -0,0 +1,47 @@
+#include "all.qh"
+
+#include "all.inc"
+
+// MONSTER PLUGIN SYSTEM
+entity monster_info[MON_MAXCOUNT];
+entity dummy_monster_info;
+
+void register_monster(int id, float(float) func, int monsterflags, vector min_s, vector max_s, string modelname, string shortname, string mname)
+{
+       entity e;
+       monster_info[id - 1] = e = spawn();
+       e.classname = "monster_info";
+       e.monsterid = id;
+       e.netname = shortname;
+       e.monster_name = mname;
+       e.monster_func = func;
+       e.mdl = modelname;
+       e.spawnflags = monsterflags;
+       e.mins = min_s;
+       e.maxs = max_s;
+       e.model = strzone(strcat("models/monsters/", modelname));
+}
+float m_null(float dummy) { return 0; }
+void register_monsters_done()
+{
+       dummy_monster_info = spawn();
+       dummy_monster_info.classname = "monster_info";
+       dummy_monster_info.monsterid = 0; // you can recognize dummies by this
+       dummy_monster_info.netname = "";
+       dummy_monster_info.monster_name = "Monster";
+       dummy_monster_info.monster_func = m_null;
+       dummy_monster_info.mdl = "";
+       dummy_monster_info.mins = '-0 -0 -0';
+       dummy_monster_info.maxs = '0 0 0';
+       dummy_monster_info.model = "";
+}
+entity get_monsterinfo(int id)
+{
+       entity m;
+       if(id < MON_FIRST || id > MON_LAST)
+               return dummy_monster_info;
+       m = monster_info[id - 1];
+       if(m)
+               return m;
+       return dummy_monster_info;
+}
diff --git a/qcsrc/common/monsters/all.qh b/qcsrc/common/monsters/all.qh
new file mode 100644 (file)
index 0000000..ce02312
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef MONSTERS_ALL_H
+#define MONSTERS_ALL_H
+
+#include "../util.qh"
+
+// monster requests
+const int MR_SETUP = 1; // (SERVER) setup monster data
+const int MR_THINK = 2; // (SERVER) logic to run every frame
+const int MR_DEATH = 3; // (SERVER) called when monster dies
+const int MR_PRECACHE = 4; // (BOTH) precaches models/sounds used by this monster
+
+// functions:
+entity get_monsterinfo(float id);
+
+// special spawn flags
+const int MONSTER_RESPAWN_DEATHPOINT = 16; // re-spawn where we died
+const int MONSTER_TYPE_FLY = 32;
+const int MONSTER_TYPE_SWIM = 64;
+const int MONSTER_SIZE_BROKEN = 128; // TODO: remove when bad models are replaced
+const int MON_FLAG_SUPERMONSTER = 256; // incredibly powerful monster
+const int MON_FLAG_RANGED = 512; // monster shoots projectiles
+const int MON_FLAG_MELEE = 1024;
+
+// entity properties of monsterinfo:
+.float monsterid; // MON_...
+.string netname; // short name
+.string monster_name; // human readable name
+.float(float) monster_func; // m_...
+.string mdl; // currently a copy of the model
+.string model; // full name of model
+.int spawnflags;
+.vector mins, maxs; // monster hitbox size
+
+// other useful macros
+#define MON_ACTION(monstertype,mrequest) (get_monsterinfo(monstertype)).monster_func(mrequest)
+#define M_NAME(monstertype) (get_monsterinfo(monstertype)).monster_name
+
+// =====================
+//     Monster Registration
+// =====================
+
+float m_null(float dummy);
+void register_monster(float id, float(float) func, float monsterflags, vector min_s, vector max_s, string modelname, string shortname, string mname);
+void register_monsters_done();
+
+const int MON_MAXCOUNT = 24;
+const int MON_FIRST = 1;
+int MON_COUNT;
+int MON_LAST;
+
+#define REGISTER_MONSTER_2(id,func,monsterflags,min_s,max_s,modelname,shortname,mname) \
+       int id; \
+       float func(float); \
+       void RegisterMonsters_##id() \
+       { \
+               MON_LAST = (id = MON_FIRST + MON_COUNT); \
+               ++MON_COUNT; \
+               register_monster(id,func,monsterflags,min_s,max_s,modelname,shortname,mname); \
+       } \
+       ACCUMULATE_FUNCTION(RegisterMonsters, RegisterMonsters_##id)
+#ifdef MENUQC
+#define REGISTER_MONSTER(id,func,monsterflags,min_s,max_s,modelname,shortname,mname) \
+       REGISTER_MONSTER_2(MON_##id,m_null,monsterflags,min_s,max_s,modelname,shortname,mname)
+#else
+#define REGISTER_MONSTER(id,func,monsterflags,min_s,max_s,modelname,shortname,mname) \
+       REGISTER_MONSTER_2(MON_##id,func,monsterflags,min_s,max_s,modelname,shortname,mname)
+#endif
+
+#include "all.inc"
+
+#undef REGISTER_MONSTER
+ACCUMULATE_FUNCTION(RegisterMonsters, register_monsters_done);
+#endif
diff --git a/qcsrc/common/monsters/monsters.qc b/qcsrc/common/monsters/monsters.qc
deleted file mode 100644 (file)
index 72c5ea8..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "monsters.qh"
-
-#include "all.inc"
-
-// MONSTER PLUGIN SYSTEM
-entity monster_info[MON_MAXCOUNT];
-entity dummy_monster_info;
-
-void register_monster(int id, float(float) func, int monsterflags, vector min_s, vector max_s, string modelname, string shortname, string mname)
-{
-       entity e;
-       monster_info[id - 1] = e = spawn();
-       e.classname = "monster_info";
-       e.monsterid = id;
-       e.netname = shortname;
-       e.monster_name = mname;
-       e.monster_func = func;
-       e.mdl = modelname;
-       e.spawnflags = monsterflags;
-       e.mins = min_s;
-       e.maxs = max_s;
-       e.model = strzone(strcat("models/monsters/", modelname));
-}
-float m_null(float dummy) { return 0; }
-void register_monsters_done()
-{
-       dummy_monster_info = spawn();
-       dummy_monster_info.classname = "monster_info";
-       dummy_monster_info.monsterid = 0; // you can recognize dummies by this
-       dummy_monster_info.netname = "";
-       dummy_monster_info.monster_name = "Monster";
-       dummy_monster_info.monster_func = m_null;
-       dummy_monster_info.mdl = "";
-       dummy_monster_info.mins = '-0 -0 -0';
-       dummy_monster_info.maxs = '0 0 0';
-       dummy_monster_info.model = "";
-}
-entity get_monsterinfo(int id)
-{
-       entity m;
-       if(id < MON_FIRST || id > MON_LAST)
-               return dummy_monster_info;
-       m = monster_info[id - 1];
-       if(m)
-               return m;
-       return dummy_monster_info;
-}
diff --git a/qcsrc/common/monsters/monsters.qh b/qcsrc/common/monsters/monsters.qh
deleted file mode 100644 (file)
index 4aa1f7e..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef MONSTERS_H
-#define MONSTERS_H
-
-#include "../util.qh"
-
-// monster requests
-const int MR_SETUP = 1; // (SERVER) setup monster data
-const int MR_THINK = 2; // (SERVER) logic to run every frame
-const int MR_DEATH = 3; // (SERVER) called when monster dies
-const int MR_PRECACHE = 4; // (BOTH) precaches models/sounds used by this monster
-
-// functions:
-entity get_monsterinfo(float id);
-
-// special spawn flags
-const int MONSTER_RESPAWN_DEATHPOINT = 16; // re-spawn where we died
-const int MONSTER_TYPE_FLY = 32;
-const int MONSTER_TYPE_SWIM = 64;
-const int MONSTER_SIZE_BROKEN = 128; // TODO: remove when bad models are replaced
-const int MON_FLAG_SUPERMONSTER = 256; // incredibly powerful monster
-const int MON_FLAG_RANGED = 512; // monster shoots projectiles
-const int MON_FLAG_MELEE = 1024;
-
-// entity properties of monsterinfo:
-.float monsterid; // MON_...
-.string netname; // short name
-.string monster_name; // human readable name
-.float(float) monster_func; // m_...
-.string mdl; // currently a copy of the model
-.string model; // full name of model
-.int spawnflags;
-.vector mins, maxs; // monster hitbox size
-
-// other useful macros
-#define MON_ACTION(monstertype,mrequest) (get_monsterinfo(monstertype)).monster_func(mrequest)
-#define M_NAME(monstertype) (get_monsterinfo(monstertype)).monster_name
-
-// =====================
-//     Monster Registration
-// =====================
-
-float m_null(float dummy);
-void register_monster(float id, float(float) func, float monsterflags, vector min_s, vector max_s, string modelname, string shortname, string mname);
-void register_monsters_done();
-
-const int MON_MAXCOUNT = 24;
-const int MON_FIRST = 1;
-int MON_COUNT;
-int MON_LAST;
-
-#define REGISTER_MONSTER_2(id,func,monsterflags,min_s,max_s,modelname,shortname,mname) \
-       int id; \
-       float func(float); \
-       void RegisterMonsters_##id() \
-       { \
-               MON_LAST = (id = MON_FIRST + MON_COUNT); \
-               ++MON_COUNT; \
-               register_monster(id,func,monsterflags,min_s,max_s,modelname,shortname,mname); \
-       } \
-       ACCUMULATE_FUNCTION(RegisterMonsters, RegisterMonsters_##id)
-#ifdef MENUQC
-#define REGISTER_MONSTER(id,func,monsterflags,min_s,max_s,modelname,shortname,mname) \
-       REGISTER_MONSTER_2(MON_##id,m_null,monsterflags,min_s,max_s,modelname,shortname,mname)
-#else
-#define REGISTER_MONSTER(id,func,monsterflags,min_s,max_s,modelname,shortname,mname) \
-       REGISTER_MONSTER_2(MON_##id,func,monsterflags,min_s,max_s,modelname,shortname,mname)
-#endif
-
-#include "all.inc"
-
-#undef REGISTER_MONSTER
-ACCUMULATE_FUNCTION(RegisterMonsters, register_monsters_done);
-#endif
index 8aee54b..5bfef1b 100644 (file)
@@ -3,7 +3,7 @@
 #elif defined(SVQC)
        #include "../../dpdefs/progsdefs.qh"
     #include "../util.qh"
-    #include "monsters.qh"
+    #include "all.qh"
     #include "sv_monsters.qh"
     #include "spawn.qh"
     #include "../../server/autocvars.qh"
index 3ff926b..ce25475 100644 (file)
@@ -7,9 +7,9 @@
     #include "../constants.qh"
     #include "../teams.qh"
     #include "../util.qh"
-    #include "monsters.qh"
+    #include "all.qh"
     #include "sv_monsters.qh"
-    #include "../weapons/weapons.qh"
+    #include "../weapons/all.qh"
     #include "../../server/autocvars.qh"
     #include "../../server/defs.qh"
     #include "../deathtypes.qh"
diff --git a/qcsrc/common/oo.qh b/qcsrc/common/oo.qh
new file mode 100644 (file)
index 0000000..63b1708
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef OO_H
+#define OO_H
+
+#ifdef MENUQC
+       #define NULL (null_entity)
+#else
+       #define NULL (world)
+#endif
+
+.string classname;
+.string vtblname;
+.entity vtblbase;
+entity spawnVtbl(entity this, entity base)
+{
+       entity vtbl = spawn();
+       copyentity(this, vtbl);
+       vtbl.vtblname = vtbl.classname;
+       vtbl.classname = "vtbl";
+       vtbl.vtblbase = base ? base : vtbl; // Top level objects use vtbl as base
+       return vtbl;
+}
+
+entity Object_vtbl;
+entity spawnObject(entity this, entity)
+{
+       this = spawn();
+       this.classname = "Object";
+       if (!Object_vtbl) Object_vtbl = spawnVtbl(this, NULL);
+       return this;
+}
+
+// Classes have a `spawn##cname(entity, entity)` constructor
+// The parameters are used as locals for [[accumulate]]
+
+// Macro to hide this implementation detail
+#define NEW(cname) (spawn##cname(NULL, NULL))
+
+#define CLASS(cname, base)                                                     \
+entity spawn##cname(entity this, entity basevtbl) {                            \
+    this = NEW(base); basevtbl = base##_vtbl;                                  \
+}
+
+#define METHOD(cname, name, prototype)                                         \
+prototype cname##_##name;                                                      \
+.prototype name;                                                               \
+[[accumulate]] entity spawn##cname(entity this, entity basevtbl) {             \
+    this.name = cname##_##name;                                                \
+}
+
+#define ATTRIB(cname, name, type, val)                                         \
+.type name;                                                                    \
+[[accumulate]] entity spawn##cname(entity this, entity basevtbl) {             \
+    this.name = val;                                                           \
+}
+
+#define ATTRIBARRAY(cname, name, type, cnt)                                    \
+.type name[cnt];
+
+#define ENDCLASS(cname)                                                        \
+.bool instanceOf##cname;                                                       \
+entity cname##_vtbl;                                                           \
+[[accumulate]] [[last]] entity spawn##cname(entity this, entity basevtbl) {    \
+    this.instanceOf##cname = true;                                             \
+    this.classname = #cname;                                                   \
+    if (!cname##_vtbl) cname##_vtbl = spawnVtbl(this, basevtbl);               \
+    return this;                                                               \
+}
+
+#define SUPER(cname) (cname##_vtbl.vtblbase)
+
+#endif
index 5890fb8..e46e12f 100644 (file)
@@ -6,7 +6,7 @@
     #include "constants.qh"
     #include "util.qh"
     #include "urllib.qh"
-    #include "weapons/weapons.qh"
+    #include "weapons/all.qh"
     #include "../server/weapons/accuracy.qh"
     #include "../server/defs.qh"
     #include "playerstats.qh"
index a1ac7dc..9d60ae0 100644 (file)
 [[deprecated("use true")]] [[alias("true")]] const bool TRUE;
 [[deprecated("use false")]] [[alias("false")]] const bool FALSE;
 
+#ifdef GMQCC
+    #define OVERLOAD(F, ...) F##_##__VA_COUNT__(__VA_ARGS__)
+#else
+    #define OVERLOAD_(F,_9,_8,_7,_6,_5,_4,_3,_2,_1,n,...) F##_##n
+    #define OVERLOAD(F, ...) OVERLOAD_(F,__VA_ARGS__,9,8,7,6,5,4,3,2,1)(__VA_ARGS__)
+#endif
+
+#define LAMBDA(...) { __VA_ARGS__ ; }
+
+#define MAP(f, ...) OVERLOAD(MAP, f, __VA_ARGS__)
+#define MAP_2(f, it) f(it)
+#define MAP_3(f, it, ...) f(it)MAP_2(f, __VA_ARGS__)
+#define MAP_4(f, it, ...) f(it)MAP_3(f, __VA_ARGS__)
+#define MAP_5(f, it, ...) f(it)MAP_4(f, __VA_ARGS__)
+#define MAP_6(f, it, ...) f(it)MAP_5(f, __VA_ARGS__)
+#define MAP_7(f, it, ...) f(it)MAP_6(f, __VA_ARGS__)
+#define MAP_8(f, it, ...) f(it)MAP_7(f, __VA_ARGS__)
+#define MAP_9(f, it, ...) f(it)MAP_8(f, __VA_ARGS__)
+#define MAP_10(f, it, ...) f(it)MAP_9(f, __VA_ARGS__)
+#define MAP_11(f, it, ...) f(it)MAP_10(f, __VA_ARGS__)
+#define MAP_12(f, it, ...) f(it)MAP_11(f, __VA_ARGS__)
+#define MAP_13(f, it, ...) f(it)MAP_12(f, __VA_ARGS__)
+#define MAP_14(f, it, ...) f(it)MAP_13(f, __VA_ARGS__)
+#define MAP_15(f, it, ...) f(it)MAP_14(f, __VA_ARGS__)
+#define MAP_16(f, it, ...) f(it)MAP_15(f, __VA_ARGS__)
+#define MAP_17(f, it, ...) f(it)MAP_16(f, __VA_ARGS__)
+#define MAP_18(f, it, ...) f(it)MAP_17(f, __VA_ARGS__)
+#define MAP_19(f, it, ...) f(it)MAP_18(f, __VA_ARGS__)
+#define MAP_20(f, it, ...) f(it)MAP_19(f, __VA_ARGS__)
+
+#define IDENTITY(it) it
+
+#define UNWORDS(...) MAP(IDENTITY, __VA_ARGS__)
+
+#define APPLY(f, ...) f(__VA_ARGS__)
+
+#ifdef SVQC
+    #define SV(f, ...) f(__VA_ARGS__)
+#else
+    #define SV(f, ...)
+#endif
+
+#ifdef CSQC
+    #define CL(f, ...) f(__VA_ARGS__)
+#else
+    #define CL(f, ...)
+#endif
+
+#define IF(cond, f, ...) cond(f, __VA_ARGS__)
+
+#define GET(name) name##get
+#define GETTER(type, name) type GET(name)() { return name; }
+
 #define BIT(n) (1 << (n))
-#define BITSET(var, mask, flag) (flag ? (var) | (mask) : (var) &~ (mask))
+#ifndef BRANCHLESS_BITSET
+    #define BITSET(var, mask, flag) (flag ? (var) | (mask) : (var) &~ (mask))
+#else
+    #define BITSET(var, mask, flag) ((var) ^ (-(flag) ^ (var)) & (mask))
+#endif
 
 #endif
diff --git a/qcsrc/common/weapons/all.qc b/qcsrc/common/weapons/all.qc
new file mode 100644 (file)
index 0000000..847c837
--- /dev/null
@@ -0,0 +1,375 @@
+#ifndef WEAPONS_ALL_C
+#define WEAPONS_ALL_C
+
+#include "all.qh"
+
+#if defined(CSQC)
+       #include "../../dpdefs/csprogsdefs.qh"
+       #include "../../client/defs.qh"
+       #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 "../buffs.qh"
+       #include "../../client/autocvars.qh"
+       #include "../deathtypes.qh"
+       #include "../../csqcmodellib/interpolate.qh"
+       #include "../../client/movetypes.qh"
+       #include "../../client/main.qh"
+       #include "../../csqcmodellib/cl_model.qh"
+#elif defined(MENUQC)
+#elif defined(SVQC)
+       #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 "../constants.qh"
+    #include "../stats.qh"
+    #include "../teams.qh"
+    #include "../util.qh"
+    #include "../buffs.qh"
+    #include "../monsters/all.qh"
+    #include "config.qh"
+    #include "../../server/weapons/csqcprojectile.qh"
+    #include "../../server/weapons/tracing.qh"
+    #include "../../server/t_items.qh"
+    #include "../../server/autocvars.qh"
+    #include "../../server/constants.qh"
+    #include "../../server/defs.qh"
+    #include "../notifications.qh"
+    #include "../deathtypes.qh"
+    #include "../../server/mutators/mutators_include.qh"
+    #include "../mapinfo.qh"
+    #include "../../server/command/common.qh"
+    #include "../../csqcmodellib/sv_model.qh"
+    #include "../../server/portals.qh"
+    #include "../../server/g_hook.qh"
+#endif
+#ifndef MENUQC
+#include "calculations.qc"
+#endif
+#include "all.inc"
+
+// WEAPON PLUGIN SYSTEM
+entity weapon_info[WEP_MAXCOUNT];
+entity dummy_weapon_info;
+
+#if WEP_MAXCOUNT > 72
+# error Kein Weltraum links auf dem Gerät
+#endif
+
+WepSet WepSet_FromWeapon(int a) {
+       a -= WEP_FIRST;
+#if WEP_MAXCOUNT > 24
+       if(a >= 24) {
+               a -= 24;
+#if WEP_MAXCOUNT > 48
+               if(a >= 24) {
+                       a -= 24;
+                       return '0 0 1' * power2of(a);
+               }
+#endif
+               return '0 1 0' * power2of(a);
+       }
+#endif
+       return '1 0 0' * power2of(a);
+}
+#ifdef SVQC
+void WepSet_AddStat()
+{
+       addstat(STAT_WEAPONS, AS_INT, weapons_x);
+#if WEP_MAXCOUNT > 24
+       addstat(STAT_WEAPONS2, AS_INT, weapons_y);
+#if WEP_MAXCOUNT > 48
+       addstat(STAT_WEAPONS3, AS_INT, weapons_z);
+#endif
+#endif
+}
+void WriteWepSet(float dst, WepSet w)
+{
+#if WEP_MAXCOUNT > 48
+       WriteInt72_t(dst, w);
+#elif WEP_MAXCOUNT > 24
+       WriteInt48_t(dst, w);
+#else
+       WriteInt24_t(dst, w.x);
+#endif
+}
+#endif
+#ifdef CSQC
+WepSet WepSet_GetFromStat()
+{
+       WepSet w = '0 0 0';
+       w.x = getstati(STAT_WEAPONS);
+#if WEP_MAXCOUNT > 24
+       w.y = getstati(STAT_WEAPONS2);
+#if WEP_MAXCOUNT > 48
+       w.z = getstati(STAT_WEAPONS3);
+#endif
+#endif
+       return w;
+}
+WepSet ReadWepSet()
+{
+#if WEP_MAXCOUNT > 48
+       return ReadInt72_t();
+#elif WEP_MAXCOUNT > 24
+       return ReadInt48_t();
+#else
+       return ReadInt24_t() * '1 0 0';
+#endif
+}
+#endif
+
+void register_weapon(
+       int id,
+       WepSet bit,
+       bool(int) func,
+       .int ammotype,
+       int i,
+       int weapontype,
+       float pickupbasevalue,
+       vector clr,
+       string modelname,
+       string simplemdl,
+       string crosshair,
+       string wepimg,
+       string refname,
+       string wepname)
+{
+       entity e;
+       weapon_info[id - 1] = e = spawn();
+       e.classname = "weapon_info";
+       e.weapon = id;
+       e.weapons = bit;
+       e.weapon_func = func;
+       e.ammo_field = ammotype;
+       e.impulse = i;
+       e.spawnflags = weapontype;
+       e.bot_pickupbasevalue = pickupbasevalue;
+       e.wpcolor = clr;
+       e.wpmodel = strzone(strcat("wpn-", ftos(id)));
+       e.mdl = modelname;
+       e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
+       e.w_simplemdl = strzone(simplemdl); // simpleitems weapon model/image
+       e.w_crosshair = strzone(car(crosshair));
+       string s = cdr(crosshair);
+       e.w_crosshair_size = ((s != "") ? stof(s) : 1); // so that we can scale the crosshair from code (for compat)
+       e.model2 = strzone(wepimg);
+       e.netname = refname;
+       e.message = wepname;
+
+       #ifdef CSQC
+       func(WR_INIT);
+       #endif
+}
+bool w_null(int dummy)
+{
+       return 0;
+}
+void register_weapons_done()
+{
+       dummy_weapon_info = spawn();
+       dummy_weapon_info.classname = "weapon_info";
+       dummy_weapon_info.weapon = 0; // you can recognize dummies by this
+       dummy_weapon_info.weapons = '0 0 0';
+       dummy_weapon_info.netname = "";
+       dummy_weapon_info.message = "AOL CD Thrower";
+       dummy_weapon_info.weapon_func = w_null;
+       dummy_weapon_info.wpmodel = "";
+       dummy_weapon_info.mdl = "";
+       dummy_weapon_info.model = "";
+       dummy_weapon_info.spawnflags = 0;
+       dummy_weapon_info.impulse = -1;
+       dummy_weapon_info.bot_pickupbasevalue = 0;
+       dummy_weapon_info.ammo_field = ammo_none;
+
+       dummy_weapon_info.w_crosshair = "gfx/crosshair1";
+       dummy_weapon_info.w_crosshair_size = 1;
+       dummy_weapon_info.model2 = "";
+
+       int i;
+       weaponorder_byid = "";
+       for(i = WEP_MAXCOUNT; i >= 1; --i)
+               if(weapon_info[i-1])
+                       weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
+       weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
+}
+entity get_weaponinfo(int id)
+{
+       entity w;
+       if(id < WEP_FIRST || id > WEP_LAST)
+               return dummy_weapon_info;
+       w = weapon_info[id - 1];
+       if(w)
+               return w;
+       return dummy_weapon_info;
+}
+string W_FixWeaponOrder(string order, float complete)
+{
+       return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
+}
+string W_NameWeaponOrder_MapFunc(string s)
+{
+       entity wi;
+       if(s == "0" || stof(s))
+       {
+               wi = get_weaponinfo(stof(s));
+               if(wi != dummy_weapon_info)
+                       return wi.netname;
+       }
+       return s;
+}
+
+string W_UndeprecateName(string s)
+{
+       switch ( s )
+       {
+               case "nex"            : return "vortex";
+               case "rocketlauncher" : return "devastator";
+               case "laser"          : return "blaster";
+               case "minstanex"      : return "vaporizer";
+               case "grenadelauncher": return "mortar";
+               case "uzi"            : return "machinegun";
+               default               : return s;
+       }
+}
+string W_NameWeaponOrder(string order)
+{
+       return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
+}
+string W_NumberWeaponOrder_MapFunc(string s)
+{
+       int i;
+       if(s == "0" || stof(s))
+               return s;
+       s = W_UndeprecateName(s);
+       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+               if(s == get_weaponinfo(i).netname)
+                       return ftos(i);
+       return s;
+}
+string W_NumberWeaponOrder(string order)
+{
+       return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
+}
+
+float W_FixWeaponOrder_BuildImpulseList_buf[WEP_MAXCOUNT];
+string W_FixWeaponOrder_BuildImpulseList_order;
+void W_FixWeaponOrder_BuildImpulseList_swap(int i, int j, entity pass)
+{
+       float h;
+       h = W_FixWeaponOrder_BuildImpulseList_buf[i];
+       W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
+       W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
+}
+float W_FixWeaponOrder_BuildImpulseList_cmp(int i, int j, entity pass)
+{
+       entity e1, e2;
+       float d;
+       e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
+       e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
+       d = (e1.impulse + 9) % 10 - (e2.impulse + 9) % 10;
+       if(d != 0)
+               return -d; // high impulse first!
+       return
+               strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
+               -
+               strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
+               ; // low char index first!
+}
+string W_FixWeaponOrder_BuildImpulseList(string o)
+{
+       int i;
+       W_FixWeaponOrder_BuildImpulseList_order = o;
+       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+               W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
+       heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
+       o = "";
+       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+               o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
+       W_FixWeaponOrder_BuildImpulseList_order = string_null;
+       return substring(o, 1, -1);
+}
+
+string W_FixWeaponOrder_AllowIncomplete(string order)
+{
+       return W_FixWeaponOrder(order, 0);
+}
+
+string W_FixWeaponOrder_ForceComplete(string order)
+{
+       if(order == "")
+               order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
+       return W_FixWeaponOrder(order, 1);
+}
+
+void W_RandomWeapons(entity e, float n)
+{
+       int i, j;
+       WepSet remaining;
+       WepSet result;
+       remaining = e.weapons;
+       result = '0 0 0';
+       for(i = 0; i < n; ++i)
+       {
+               RandomSelection_Init();
+               for(j = WEP_FIRST; j <= WEP_LAST; ++j)
+                       if(remaining & WepSet_FromWeapon(j))
+                               RandomSelection_Add(world, j, string_null, 1, 1);
+               result |= WepSet_FromWeapon(RandomSelection_chosen_float);
+               remaining &= ~WepSet_FromWeapon(RandomSelection_chosen_float);
+       }
+       e.weapons = result;
+}
+
+string GetAmmoPicture(.int ammotype)
+{
+       switch(ammotype)
+       {
+               case ammo_shells:  return "ammo_shells";
+               case ammo_nails:   return "ammo_bullets";
+               case ammo_rockets: return "ammo_rockets";
+               case ammo_cells:   return "ammo_cells";
+               case ammo_plasma:  return "ammo_cells";
+               case ammo_fuel:    return "ammo_fuel";
+               default: return ""; // wtf, no ammo type?
+       }
+}
+
+#ifdef CSQC
+.int GetAmmoFieldFromNum(int i)
+{
+       switch(i)
+       {
+               case 0: return ammo_shells;
+               case 1: return ammo_nails;
+               case 2: return ammo_rockets;
+               case 3: return ammo_cells;
+               case 4: return ammo_plasma;
+               case 5: return ammo_fuel;
+               default: return ammo_none;
+       }
+}
+
+int GetAmmoStat(.int ammotype)
+{
+       switch(ammotype)
+       {
+               case ammo_shells: return STAT_SHELLS;
+               case ammo_nails: return STAT_NAILS;
+               case ammo_rockets: return STAT_ROCKETS;
+               case ammo_cells: return STAT_CELLS;
+               case ammo_plasma: return STAT_PLASMA;
+               case ammo_fuel: return STAT_FUEL;
+               default: return -1;
+       }
+}
+#endif
+#endif
diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh
new file mode 100644 (file)
index 0000000..154f816
--- /dev/null
@@ -0,0 +1,217 @@
+#ifndef WEAPONS_ALL_H
+#define WEAPONS_ALL_H
+
+#ifndef MENUQC
+#include "calculations.qh"
+#endif
+
+#include "../util.qh"
+#ifdef SVQC
+#include "../../server/bot/aim.qh"
+#endif
+const int MAX_SHOT_DISTANCE = 32768;
+
+// weapon pickup ratings for bot logic
+const int BOT_PICKUP_RATING_LOW  =  2500;
+const int BOT_PICKUP_RATING_MID  =  5000;
+const int BOT_PICKUP_RATING_HIGH = 10000;
+
+// weapon flags
+const int WEP_TYPE_OTHER          =  0x00; // not for damaging people
+const int WEP_TYPE_SPLASH         =  0x01; // splash damage
+const int WEP_TYPE_HITSCAN        =  0x02; // hitscan
+const int WEP_TYPEMASK            =  0x0F;
+const int WEP_FLAG_CANCLIMB       =  0x10; // can be used for movement
+const int WEP_FLAG_NORMAL         =  0x20; // in "most weapons" set
+const int WEP_FLAG_HIDDEN         =  0x40; // hides from menu
+const int WEP_FLAG_RELOADABLE     =  0x80; // can has reload
+const int WEP_FLAG_SUPERWEAPON    = 0x100; // powerup timer
+const int WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
+
+// weapon requests
+const int WR_SETUP          =  1; // (SERVER) setup weapon data
+const int WR_THINK          =  2; // (SERVER) logic to run every frame
+const int WR_CHECKAMMO1     =  3; // (SERVER) checks ammo for weapon primary
+const int WR_CHECKAMMO2     =  4; // (SERVER) checks ammo for weapon second
+const int WR_AIM            =  5; // (SERVER) runs bot aiming code for this weapon
+const int WR_INIT           =  6; // (BOTH)   precaches models/sounds used by this weapon, also sets up weapon properties
+const int WR_SUICIDEMESSAGE =  7; // (SERVER) notification number for suicide message (may inspect w_deathtype for details)
+const int WR_KILLMESSAGE    =  8; // (SERVER) notification number for kill message (may inspect w_deathtype for details)
+const int WR_RELOAD         =  9; // (SERVER) handles reloading for weapon
+const int WR_RESETPLAYER    = 10; // (SERVER) clears fields that the weapon may use
+const int WR_IMPACTEFFECT   = 11; // (CLIENT) impact effect for weapon explosion
+const int WR_PLAYERDEATH    = 12; // (SERVER) called whenever a player dies
+const int WR_GONETHINK      = 13; // (SERVER) logic to run when weapon is lost
+const int WR_CONFIG         = 14; // (ALL)    dump weapon cvars to config in data directory (see: sv_cmd dumpweapons)
+const int WR_ZOOMRETICLE    = 15; // (CLIENT) weapon specific zoom reticle
+const int WR_DROP           = 16; // (SERVER) the weapon is dropped
+const int WR_PICKUP         = 17; // (SERVER) a weapon is picked up
+
+// variables:
+string weaponorder_byid;
+
+// weapon sets
+typedef vector WepSet;
+WepSet WepSet_FromWeapon(int a);
+#ifdef SVQC
+void WepSet_AddStat();
+void WriteWepSet(float dest, WepSet w);
+#endif
+#ifdef CSQC
+WepSet WepSet_GetFromStat();
+WepSet ReadWepSet();
+#endif
+
+// weapon name macros
+#define WEP_FIRST 1
+#define WEP_MAXCOUNT 24 // Increase as needed. Can be up to three times as much.
+int WEP_COUNT;
+int WEP_LAST;
+WepSet WEPSET_ALL;
+WepSet WEPSET_SUPERWEAPONS;
+
+// functions:
+entity get_weaponinfo(int id);
+string W_FixWeaponOrder(string order, float complete);
+string W_UndeprecateName(string s);
+string W_NameWeaponOrder(string order);
+string W_NumberWeaponOrder(string order);
+string W_FixWeaponOrder_BuildImpulseList(string o);
+string W_FixWeaponOrder_AllowIncomplete(string order);
+string W_FixWeaponOrder_ForceComplete(string order);
+void W_RandomWeapons(entity e, float n);
+
+string GetAmmoPicture(.int ammotype);
+
+#ifdef CSQC
+.int GetAmmoFieldFromNum(int i);
+int GetAmmoStat(.int ammotype);
+#endif
+
+// ammo types
+.int ammo_shells;
+.int ammo_nails;
+.int ammo_rockets;
+.int ammo_cells;
+.int ammo_plasma;
+.int ammo_fuel;
+.int ammo_none;
+
+// other useful macros
+#define WEP_ACTION(wpn,wrequest) (get_weaponinfo(wpn)).weapon_func(wrequest)
+#define WEP_AMMO(wpn) ((get_weaponinfo(WEP_##wpn)).ammo_field) // only used inside weapon files/with direct name, don't duplicate prefix
+#define WEP_NAME(wpn) ((get_weaponinfo(wpn)).message)
+
+
+// ======================
+//  Configuration Macros
+// ======================
+
+// create cvars for weapon settings
+#define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
+
+#define WEP_ADD_CVAR_PRI(wepname,name) WEP_ADD_CVAR_NONE(wepname, primary_##name)
+#define WEP_ADD_CVAR_SEC(wepname,name) WEP_ADD_CVAR_NONE(wepname, secondary_##name)
+#define WEP_ADD_CVAR_BOTH(wepname,name) \
+       WEP_ADD_CVAR_PRI(wepname, name) \
+       WEP_ADD_CVAR_SEC(wepname, name)
+
+#define WEP_ADD_CVAR(wepid,wepname,mode,name) WEP_ADD_CVAR_##mode(wepname, name)
+
+// create properties for weapon settings
+#define WEP_ADD_PROP(wepid,wepname,type,prop,name) \
+       .type prop; \
+       [[last]] type autocvar_g_balance_##wepname##_##name;
+
+// read cvars from weapon settings
+#define WEP_CVAR(wepname,name) autocvar_g_balance_##wepname##_##name
+#define WEP_CVAR_PRI(wepname,name) WEP_CVAR(wepname, primary_##name)
+#define WEP_CVAR_SEC(wepname,name) WEP_CVAR(wepname, secondary_##name)
+#define WEP_CVAR_BOTH(wepname,isprimary,name) ((isprimary) ? WEP_CVAR_PRI(wepname, name) : WEP_CVAR_SEC(wepname, name))
+
+// set initialization values for weapon settings
+#define WEP_SKIP_CVAR(unuseda,unusedb,unusedc,unusedd) /* skip cvars */
+#define WEP_SET_PROP(wepid,wepname,type,prop,name) get_weaponinfo(WEP_##wepid).##prop = autocvar_g_balance_##wepname##_##name;
+
+
+// =====================
+//  Weapon Registration
+// =====================
+
+bool w_null(int dummy);
+
+void register_weapon(
+       int id,
+       WepSet bit,
+       bool(int) func,
+       .int ammotype,
+       int i,
+       int weapontype,
+       float pickupbasevalue,
+       vector clr,
+       string modelname,
+       string simplemdl,
+       string crosshair,
+       string wepimg,
+       string refname,
+       string wepname);
+
+void register_weapons_done();
+
+// entity properties of weaponinfo:
+// fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A"
+.int weapon;                // M: WEP_id    // WEP_...
+.WepSet weapons;            // A: WEPSET_id // WEPSET_...
+.float(float) weapon_func;  // M: function  // w_...
+..int ammo_field;         // M: ammotype  // main ammo field
+.int impulse;               // M: impulse   // weapon impulse
+.int spawnflags;            // M: flags     // WEPSPAWNFLAG_... combined
+.float bot_pickupbasevalue; // M: rating    // bot weapon priority
+.vector wpcolor;            // M: color     // waypointsprite color
+.string wpmodel;            // A: wpn-id    // wpn- sprite name
+.string mdl;                // M: modelname // name of model (without g_ v_ or h_ prefixes)
+.string model;              // A: modelname // full path to g_ model
+.string w_simplemdl;        // M: simplemdl // simpleitems weapon model/image
+.string w_crosshair;        // M: crosshair // per-weapon crosshair: "CrosshairImage Size"
+.float w_crosshair_size;    // A: crosshair // per-weapon crosshair size (argument two of "crosshair" field)
+.string model2;             // M: wepimg    // "weaponfoobar" side view image file of weapon // WEAPONTODO: Move out of skin files, move to common files
+.string netname;            // M: refname   // reference name name
+.string message;            // M: wepname   // human readable name
+
+
+// note: the fabs call is just there to hide "if result is constant" warning
+#define REGISTER_WEAPON_2(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
+       int id; \
+       WepSet bit; \
+       bool function(int); \
+       void RegisterWeapons_##id() \
+       { \
+               WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
+               bit = WepSet_FromWeapon(id); \
+               WEPSET_ALL |= bit; \
+               if((flags) & WEP_FLAG_SUPERWEAPON) \
+                       WEPSET_SUPERWEAPONS |= bit; \
+               ++WEP_COUNT; \
+               register_weapon(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname); \
+       } \
+       ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
+#ifdef MENUQC
+#define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
+       REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,w_null,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
+#else
+#define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
+       REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
+#endif
+
+#include "all.inc"
+
+#undef WEP_ADD_CVAR_MO_PRI
+#undef WEP_ADD_CVAR_MO_SEC
+#undef WEP_ADD_CVAR_MO_BOTH
+#undef WEP_ADD_CVAR_MO_NONE
+#undef WEP_ADD_CVAR
+#undef WEP_ADD_PROP
+#undef REGISTER_WEAPON
+
+ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done);
+#endif
index a314f03..0448f48 100644 (file)
@@ -5,7 +5,7 @@
     #include "../../dpdefs/dpextensions.qh"
     #include "../util.qh"
     #include "config.qh"
-    #include "weapons.qh"
+    #include "all.qh"
 #endif
 
 // ==========================
diff --git a/qcsrc/common/weapons/weapons.qc b/qcsrc/common/weapons/weapons.qc
deleted file mode 100644 (file)
index 58fdbae..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-#ifndef WEAPONS_C
-#define WEAPONS_C
-
-#include "weapons.qh"
-
-#if defined(CSQC)
-       #include "../../dpdefs/csprogsdefs.qh"
-       #include "../../client/defs.qh"
-       #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 "../buffs.qh"
-       #include "../../client/autocvars.qh"
-       #include "../deathtypes.qh"
-       #include "../../csqcmodellib/interpolate.qh"
-       #include "../../client/movetypes.qh"
-       #include "../../client/main.qh"
-       #include "../../csqcmodellib/cl_model.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
-       #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 "../constants.qh"
-    #include "../stats.qh"
-    #include "../teams.qh"
-    #include "../util.qh"
-    #include "../buffs.qh"
-    #include "../monsters/monsters.qh"
-    #include "config.qh"
-    #include "../../server/weapons/csqcprojectile.qh"
-    #include "../../server/weapons/tracing.qh"
-    #include "../../server/t_items.qh"
-    #include "../../server/autocvars.qh"
-    #include "../../server/constants.qh"
-    #include "../../server/defs.qh"
-    #include "../notifications.qh"
-    #include "../deathtypes.qh"
-    #include "../../server/mutators/mutators_include.qh"
-    #include "../mapinfo.qh"
-    #include "../../server/command/common.qh"
-    #include "../../csqcmodellib/sv_model.qh"
-    #include "../../server/portals.qh"
-    #include "../../server/g_hook.qh"
-#endif
-#ifndef MENUQC
-#include "calculations.qc"
-#endif
-#include "all.inc"
-
-// WEAPON PLUGIN SYSTEM
-entity weapon_info[WEP_MAXCOUNT];
-entity dummy_weapon_info;
-
-#if WEP_MAXCOUNT > 72
-# error Kein Weltraum links auf dem Gerät
-#endif
-
-WepSet WepSet_FromWeapon(int a) {
-       a -= WEP_FIRST;
-#if WEP_MAXCOUNT > 24
-       if(a >= 24) {
-               a -= 24;
-#if WEP_MAXCOUNT > 48
-               if(a >= 24) {
-                       a -= 24;
-                       return '0 0 1' * power2of(a);
-               }
-#endif
-               return '0 1 0' * power2of(a);
-       }
-#endif
-       return '1 0 0' * power2of(a);
-}
-#ifdef SVQC
-void WepSet_AddStat()
-{
-       addstat(STAT_WEAPONS, AS_INT, weapons_x);
-#if WEP_MAXCOUNT > 24
-       addstat(STAT_WEAPONS2, AS_INT, weapons_y);
-#if WEP_MAXCOUNT > 48
-       addstat(STAT_WEAPONS3, AS_INT, weapons_z);
-#endif
-#endif
-}
-void WriteWepSet(float dst, WepSet w)
-{
-#if WEP_MAXCOUNT > 48
-       WriteInt72_t(dst, w);
-#elif WEP_MAXCOUNT > 24
-       WriteInt48_t(dst, w);
-#else
-       WriteInt24_t(dst, w.x);
-#endif
-}
-#endif
-#ifdef CSQC
-WepSet WepSet_GetFromStat()
-{
-       WepSet w = '0 0 0';
-       w.x = getstati(STAT_WEAPONS);
-#if WEP_MAXCOUNT > 24
-       w.y = getstati(STAT_WEAPONS2);
-#if WEP_MAXCOUNT > 48
-       w.z = getstati(STAT_WEAPONS3);
-#endif
-#endif
-       return w;
-}
-WepSet ReadWepSet()
-{
-#if WEP_MAXCOUNT > 48
-       return ReadInt72_t();
-#elif WEP_MAXCOUNT > 24
-       return ReadInt48_t();
-#else
-       return ReadInt24_t() * '1 0 0';
-#endif
-}
-#endif
-
-void register_weapon(
-       int id,
-       WepSet bit,
-       bool(int) func,
-       .int ammotype,
-       int i,
-       int weapontype,
-       float pickupbasevalue,
-       vector clr,
-       string modelname,
-       string simplemdl,
-       string crosshair,
-       string wepimg,
-       string refname,
-       string wepname)
-{
-       entity e;
-       weapon_info[id - 1] = e = spawn();
-       e.classname = "weapon_info";
-       e.weapon = id;
-       e.weapons = bit;
-       e.weapon_func = func;
-       e.ammo_field = ammotype;
-       e.impulse = i;
-       e.spawnflags = weapontype;
-       e.bot_pickupbasevalue = pickupbasevalue;
-       e.wpcolor = clr;
-       e.wpmodel = strzone(strcat("wpn-", ftos(id)));
-       e.mdl = modelname;
-       e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
-       e.w_simplemdl = strzone(simplemdl); // simpleitems weapon model/image
-       e.w_crosshair = strzone(car(crosshair));
-       string s = cdr(crosshair);
-       e.w_crosshair_size = ((s != "") ? stof(s) : 1); // so that we can scale the crosshair from code (for compat)
-       e.model2 = strzone(wepimg);
-       e.netname = refname;
-       e.message = wepname;
-
-       #ifdef CSQC
-       func(WR_INIT);
-       #endif
-}
-bool w_null(int dummy)
-{
-       return 0;
-}
-void register_weapons_done()
-{
-       dummy_weapon_info = spawn();
-       dummy_weapon_info.classname = "weapon_info";
-       dummy_weapon_info.weapon = 0; // you can recognize dummies by this
-       dummy_weapon_info.weapons = '0 0 0';
-       dummy_weapon_info.netname = "";
-       dummy_weapon_info.message = "AOL CD Thrower";
-       dummy_weapon_info.weapon_func = w_null;
-       dummy_weapon_info.wpmodel = "";
-       dummy_weapon_info.mdl = "";
-       dummy_weapon_info.model = "";
-       dummy_weapon_info.spawnflags = 0;
-       dummy_weapon_info.impulse = -1;
-       dummy_weapon_info.bot_pickupbasevalue = 0;
-       dummy_weapon_info.ammo_field = ammo_none;
-
-       dummy_weapon_info.w_crosshair = "gfx/crosshair1";
-       dummy_weapon_info.w_crosshair_size = 1;
-       dummy_weapon_info.model2 = "";
-
-       int i;
-       weaponorder_byid = "";
-       for(i = WEP_MAXCOUNT; i >= 1; --i)
-               if(weapon_info[i-1])
-                       weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
-       weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
-}
-entity get_weaponinfo(int id)
-{
-       entity w;
-       if(id < WEP_FIRST || id > WEP_LAST)
-               return dummy_weapon_info;
-       w = weapon_info[id - 1];
-       if(w)
-               return w;
-       return dummy_weapon_info;
-}
-string W_FixWeaponOrder(string order, float complete)
-{
-       return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
-}
-string W_NameWeaponOrder_MapFunc(string s)
-{
-       entity wi;
-       if(s == "0" || stof(s))
-       {
-               wi = get_weaponinfo(stof(s));
-               if(wi != dummy_weapon_info)
-                       return wi.netname;
-       }
-       return s;
-}
-
-string W_UndeprecateName(string s)
-{
-       switch ( s )
-       {
-               case "nex"            : return "vortex";
-               case "rocketlauncher" : return "devastator";
-               case "laser"          : return "blaster";
-               case "minstanex"      : return "vaporizer";
-               case "grenadelauncher": return "mortar";
-               case "uzi"            : return "machinegun";
-               default               : return s;
-       }
-}
-string W_NameWeaponOrder(string order)
-{
-       return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
-}
-string W_NumberWeaponOrder_MapFunc(string s)
-{
-       int i;
-       if(s == "0" || stof(s))
-               return s;
-       s = W_UndeprecateName(s);
-       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-               if(s == get_weaponinfo(i).netname)
-                       return ftos(i);
-       return s;
-}
-string W_NumberWeaponOrder(string order)
-{
-       return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
-}
-
-float W_FixWeaponOrder_BuildImpulseList_buf[WEP_MAXCOUNT];
-string W_FixWeaponOrder_BuildImpulseList_order;
-void W_FixWeaponOrder_BuildImpulseList_swap(int i, int j, entity pass)
-{
-       float h;
-       h = W_FixWeaponOrder_BuildImpulseList_buf[i];
-       W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
-       W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
-}
-float W_FixWeaponOrder_BuildImpulseList_cmp(int i, int j, entity pass)
-{
-       entity e1, e2;
-       float d;
-       e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
-       e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
-       d = (e1.impulse + 9) % 10 - (e2.impulse + 9) % 10;
-       if(d != 0)
-               return -d; // high impulse first!
-       return
-               strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
-               -
-               strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
-               ; // low char index first!
-}
-string W_FixWeaponOrder_BuildImpulseList(string o)
-{
-       int i;
-       W_FixWeaponOrder_BuildImpulseList_order = o;
-       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-               W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
-       heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
-       o = "";
-       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-               o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
-       W_FixWeaponOrder_BuildImpulseList_order = string_null;
-       return substring(o, 1, -1);
-}
-
-string W_FixWeaponOrder_AllowIncomplete(string order)
-{
-       return W_FixWeaponOrder(order, 0);
-}
-
-string W_FixWeaponOrder_ForceComplete(string order)
-{
-       if(order == "")
-               order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
-       return W_FixWeaponOrder(order, 1);
-}
-
-void W_RandomWeapons(entity e, float n)
-{
-       int i, j;
-       WepSet remaining;
-       WepSet result;
-       remaining = e.weapons;
-       result = '0 0 0';
-       for(i = 0; i < n; ++i)
-       {
-               RandomSelection_Init();
-               for(j = WEP_FIRST; j <= WEP_LAST; ++j)
-                       if(remaining & WepSet_FromWeapon(j))
-                               RandomSelection_Add(world, j, string_null, 1, 1);
-               result |= WepSet_FromWeapon(RandomSelection_chosen_float);
-               remaining &= ~WepSet_FromWeapon(RandomSelection_chosen_float);
-       }
-       e.weapons = result;
-}
-
-string GetAmmoPicture(.int ammotype)
-{
-       switch(ammotype)
-       {
-               case ammo_shells:  return "ammo_shells";
-               case ammo_nails:   return "ammo_bullets";
-               case ammo_rockets: return "ammo_rockets";
-               case ammo_cells:   return "ammo_cells";
-               case ammo_plasma:  return "ammo_cells";
-               case ammo_fuel:    return "ammo_fuel";
-               default: return ""; // wtf, no ammo type?
-       }
-}
-
-#ifdef CSQC
-.int GetAmmoFieldFromNum(int i)
-{
-       switch(i)
-       {
-               case 0: return ammo_shells;
-               case 1: return ammo_nails;
-               case 2: return ammo_rockets;
-               case 3: return ammo_cells;
-               case 4: return ammo_plasma;
-               case 5: return ammo_fuel;
-               default: return ammo_none;
-       }
-}
-
-int GetAmmoStat(.int ammotype)
-{
-       switch(ammotype)
-       {
-               case ammo_shells: return STAT_SHELLS;
-               case ammo_nails: return STAT_NAILS;
-               case ammo_rockets: return STAT_ROCKETS;
-               case ammo_cells: return STAT_CELLS;
-               case ammo_plasma: return STAT_PLASMA;
-               case ammo_fuel: return STAT_FUEL;
-               default: return -1;
-       }
-}
-#endif
-#endif
diff --git a/qcsrc/common/weapons/weapons.qh b/qcsrc/common/weapons/weapons.qh
deleted file mode 100644 (file)
index 5f17ccb..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-#ifndef WEAPONS_H
-#define WEAPONS_H
-
-#ifndef MENUQC
-#include "calculations.qh"
-#endif
-
-#include "../util.qh"
-#ifdef SVQC
-#include "../../server/bot/aim.qh"
-#endif
-const int MAX_SHOT_DISTANCE = 32768;
-
-// weapon pickup ratings for bot logic
-const int BOT_PICKUP_RATING_LOW  =  2500;
-const int BOT_PICKUP_RATING_MID  =  5000;
-const int BOT_PICKUP_RATING_HIGH = 10000;
-
-// weapon flags
-const int WEP_TYPE_OTHER          =  0x00; // not for damaging people
-const int WEP_TYPE_SPLASH         =  0x01; // splash damage
-const int WEP_TYPE_HITSCAN        =  0x02; // hitscan
-const int WEP_TYPEMASK            =  0x0F;
-const int WEP_FLAG_CANCLIMB       =  0x10; // can be used for movement
-const int WEP_FLAG_NORMAL         =  0x20; // in "most weapons" set
-const int WEP_FLAG_HIDDEN         =  0x40; // hides from menu
-const int WEP_FLAG_RELOADABLE     =  0x80; // can has reload
-const int WEP_FLAG_SUPERWEAPON    = 0x100; // powerup timer
-const int WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
-
-// weapon requests
-const int WR_SETUP          =  1; // (SERVER) setup weapon data
-const int WR_THINK          =  2; // (SERVER) logic to run every frame
-const int WR_CHECKAMMO1     =  3; // (SERVER) checks ammo for weapon primary
-const int WR_CHECKAMMO2     =  4; // (SERVER) checks ammo for weapon second
-const int WR_AIM            =  5; // (SERVER) runs bot aiming code for this weapon
-const int WR_INIT           =  6; // (BOTH)   precaches models/sounds used by this weapon, also sets up weapon properties
-const int WR_SUICIDEMESSAGE =  7; // (SERVER) notification number for suicide message (may inspect w_deathtype for details)
-const int WR_KILLMESSAGE    =  8; // (SERVER) notification number for kill message (may inspect w_deathtype for details)
-const int WR_RELOAD         =  9; // (SERVER) handles reloading for weapon
-const int WR_RESETPLAYER    = 10; // (SERVER) clears fields that the weapon may use
-const int WR_IMPACTEFFECT   = 11; // (CLIENT) impact effect for weapon explosion
-const int WR_PLAYERDEATH    = 12; // (SERVER) called whenever a player dies
-const int WR_GONETHINK      = 13; // (SERVER) logic to run when weapon is lost
-const int WR_CONFIG         = 14; // (ALL)    dump weapon cvars to config in data directory (see: sv_cmd dumpweapons)
-const int WR_ZOOMRETICLE    = 15; // (CLIENT) weapon specific zoom reticle
-const int WR_DROP           = 16; // (SERVER) the weapon is dropped
-const int WR_PICKUP         = 17; // (SERVER) a weapon is picked up
-
-// variables:
-string weaponorder_byid;
-
-// weapon sets
-typedef vector WepSet;
-WepSet WepSet_FromWeapon(int a);
-#ifdef SVQC
-void WepSet_AddStat();
-void WriteWepSet(float dest, WepSet w);
-#endif
-#ifdef CSQC
-WepSet WepSet_GetFromStat();
-WepSet ReadWepSet();
-#endif
-
-// weapon name macros
-#define WEP_FIRST 1
-#define WEP_MAXCOUNT 24 // Increase as needed. Can be up to three times as much.
-int WEP_COUNT;
-int WEP_LAST;
-WepSet WEPSET_ALL;
-WepSet WEPSET_SUPERWEAPONS;
-
-// functions:
-entity get_weaponinfo(int id);
-string W_FixWeaponOrder(string order, float complete);
-string W_UndeprecateName(string s);
-string W_NameWeaponOrder(string order);
-string W_NumberWeaponOrder(string order);
-string W_FixWeaponOrder_BuildImpulseList(string o);
-string W_FixWeaponOrder_AllowIncomplete(string order);
-string W_FixWeaponOrder_ForceComplete(string order);
-void W_RandomWeapons(entity e, float n);
-
-string GetAmmoPicture(.int ammotype);
-
-#ifdef CSQC
-.int GetAmmoFieldFromNum(int i);
-int GetAmmoStat(.int ammotype);
-#endif
-
-// ammo types
-.int ammo_shells;
-.int ammo_nails;
-.int ammo_rockets;
-.int ammo_cells;
-.int ammo_plasma;
-.int ammo_fuel;
-.int ammo_none;
-
-// other useful macros
-#define WEP_ACTION(wpn,wrequest) (get_weaponinfo(wpn)).weapon_func(wrequest)
-#define WEP_AMMO(wpn) ((get_weaponinfo(WEP_##wpn)).ammo_field) // only used inside weapon files/with direct name, don't duplicate prefix
-#define WEP_NAME(wpn) ((get_weaponinfo(wpn)).message)
-
-
-// ======================
-//  Configuration Macros
-// ======================
-
-// create cvars for weapon settings
-#define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
-
-#define WEP_ADD_CVAR_PRI(wepname,name) WEP_ADD_CVAR_NONE(wepname, primary_##name)
-#define WEP_ADD_CVAR_SEC(wepname,name) WEP_ADD_CVAR_NONE(wepname, secondary_##name)
-#define WEP_ADD_CVAR_BOTH(wepname,name) \
-       WEP_ADD_CVAR_PRI(wepname, name) \
-       WEP_ADD_CVAR_SEC(wepname, name)
-
-#define WEP_ADD_CVAR(wepid,wepname,mode,name) WEP_ADD_CVAR_##mode(wepname, name)
-
-// create properties for weapon settings
-#define WEP_ADD_PROP(wepid,wepname,type,prop,name) \
-       .type prop; \
-       [[last]] type autocvar_g_balance_##wepname##_##name;
-
-// read cvars from weapon settings
-#define WEP_CVAR(wepname,name) autocvar_g_balance_##wepname##_##name
-#define WEP_CVAR_PRI(wepname,name) WEP_CVAR(wepname, primary_##name)
-#define WEP_CVAR_SEC(wepname,name) WEP_CVAR(wepname, secondary_##name)
-#define WEP_CVAR_BOTH(wepname,isprimary,name) ((isprimary) ? WEP_CVAR_PRI(wepname, name) : WEP_CVAR_SEC(wepname, name))
-
-// set initialization values for weapon settings
-#define WEP_SKIP_CVAR(unuseda,unusedb,unusedc,unusedd) /* skip cvars */
-#define WEP_SET_PROP(wepid,wepname,type,prop,name) get_weaponinfo(WEP_##wepid).##prop = autocvar_g_balance_##wepname##_##name;
-
-
-// =====================
-//  Weapon Registration
-// =====================
-
-bool w_null(int dummy);
-
-void register_weapon(
-       int id,
-       WepSet bit,
-       bool(int) func,
-       .int ammotype,
-       int i,
-       int weapontype,
-       float pickupbasevalue,
-       vector clr,
-       string modelname,
-       string simplemdl,
-       string crosshair,
-       string wepimg,
-       string refname,
-       string wepname);
-
-void register_weapons_done();
-
-// entity properties of weaponinfo:
-// fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A"
-.int weapon;                // M: WEP_id    // WEP_...
-.WepSet weapons;            // A: WEPSET_id // WEPSET_...
-.float(float) weapon_func;  // M: function  // w_...
-..int ammo_field;         // M: ammotype  // main ammo field
-.int impulse;               // M: impulse   // weapon impulse
-.int spawnflags;            // M: flags     // WEPSPAWNFLAG_... combined
-.float bot_pickupbasevalue; // M: rating    // bot weapon priority
-.vector wpcolor;            // M: color     // waypointsprite color
-.string wpmodel;            // A: wpn-id    // wpn- sprite name
-.string mdl;                // M: modelname // name of model (without g_ v_ or h_ prefixes)
-.string model;              // A: modelname // full path to g_ model
-.string w_simplemdl;        // M: simplemdl // simpleitems weapon model/image
-.string w_crosshair;        // M: crosshair // per-weapon crosshair: "CrosshairImage Size"
-.float w_crosshair_size;    // A: crosshair // per-weapon crosshair size (argument two of "crosshair" field)
-.string model2;             // M: wepimg    // "weaponfoobar" side view image file of weapon // WEAPONTODO: Move out of skin files, move to common files
-.string netname;            // M: refname   // reference name name
-.string message;            // M: wepname   // human readable name
-
-
-// note: the fabs call is just there to hide "if result is constant" warning
-#define REGISTER_WEAPON_2(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
-       int id; \
-       WepSet bit; \
-       bool function(int); \
-       void RegisterWeapons_##id() \
-       { \
-               WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
-               bit = WepSet_FromWeapon(id); \
-               WEPSET_ALL |= bit; \
-               if((flags) & WEP_FLAG_SUPERWEAPON) \
-                       WEPSET_SUPERWEAPONS |= bit; \
-               ++WEP_COUNT; \
-               register_weapon(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname); \
-       } \
-       ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
-#ifdef MENUQC
-#define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
-       REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,w_null,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
-#else
-#define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
-       REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
-#endif
-
-#include "all.inc"
-
-#undef WEP_ADD_CVAR_MO_PRI
-#undef WEP_ADD_CVAR_MO_SEC
-#undef WEP_ADD_CVAR_MO_BOTH
-#undef WEP_ADD_CVAR_MO_NONE
-#undef WEP_ADD_CVAR
-#undef WEP_ADD_PROP
-#undef REGISTER_WEAPON
-
-ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done);
-#endif
index cc07017..a6903ae 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef CLIENT___H
-#define CLIENT___H
+#ifndef CLIENT_ALL_H
+#define CLIENT_ALL_H
 
 #include "../dpdefs/menudefs.qh"
 #include "../dpdefs/keycodes.qh"
index 68b90d5..5b0e417 100644 (file)
@@ -34,7 +34,8 @@
 #include "xonotic/colorpicker_string.qc"
 #include "xonotic/commandbutton.qc"
 #include "xonotic/credits.qc"
-#include "xonotic/crosshairbutton.qc"
+#include "xonotic/crosshairpicker.qc"
+#include "xonotic/crosshairpreview.qc"
 #include "xonotic/cvarlist.qc"
 #include "xonotic/demolist.qc"
 #include "xonotic/dialog.qc"
 #include "xonotic/mainwindow.qc"
 #include "xonotic/maplist.qc"
 #include "xonotic/nexposee.qc"
+#include "xonotic/picker.qc"
 #include "xonotic/playerlist.qc"
 #include "xonotic/playermodel.qc"
 #include "xonotic/playlist.qc"
diff --git a/qcsrc/menu/command/all.qc b/qcsrc/menu/command/all.qc
new file mode 100644 (file)
index 0000000..711a747
--- /dev/null
@@ -0,0 +1,5 @@
+#include "../menu.qh"
+
+#include "../../common/command/all.qc"
+
+#include "menu_cmd.qc"
diff --git a/qcsrc/menu/command/all.qh b/qcsrc/menu/command/all.qh
new file mode 100644 (file)
index 0000000..7f116ae
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef MENU_COMMANDS_ALL_H
+#define MENU_COMMANDS_ALL_H
+
+#include "../../common/command/commands.qh"
+
+#include "menu_cmd.qh"
+
+#endif
diff --git a/qcsrc/menu/command/commands.qc b/qcsrc/menu/command/commands.qc
deleted file mode 100644 (file)
index 5b5911f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "../menu.qh"
-
-#include "../../common/command/commands.qc"
-
-#include "menu_cmd.qc"
diff --git a/qcsrc/menu/command/commands.qh b/qcsrc/menu/command/commands.qh
deleted file mode 100644 (file)
index 5ea3006..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef MENU_COMMANDS_H
-#define MENU_COMMANDS_H
-
-#include "../../common/command/commands.qh"
-
-#include "menu_cmd.qh"
-
-#endif
index 449bb06..ac0655c 100644 (file)
@@ -14,6 +14,7 @@ CLASS(Container, Item)
        METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector, .vector))
        METHOD(Container, addItem, void(entity, entity, vector, vector, float))
        METHOD(Container, addItemCentered, void(entity, entity, vector, float))
+       METHOD(Container, addItemRightCentered, void(entity, entity, vector, float))
        METHOD(Container, moveItemAfter, void(entity, entity, entity))
        METHOD(Container, removeItem, void(entity, entity))
        METHOD(Container, setFocus, void(entity, entity))
@@ -282,6 +283,11 @@ void Container_addItemCentered(entity me, entity other, vector theSize, float th
        me.addItem(me, other, '0.5 0.5 0' - 0.5 * theSize, theSize, theAlpha);
 }
 
+void Container_addItemRightCentered(entity me, entity other, vector theSize, float theAlpha)
+{
+       me.addItem(me, other, '1 0.5 0' - 0.5 * theSize, theSize, theAlpha);
+}
+
 void Container_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
 {
        if(other.parent)
index b6048ac..77037ac 100644 (file)
@@ -130,12 +130,15 @@ void Dialog_configureDialog(entity me)
 {
        float absWidth, absHeight;
 
-       me.frame = NEW(BorderImage);
-       me.frame.configureBorderImage(me.frame, me.title, me.titleFontSize, me.color, me.backgroundImage, me.borderLines * me.titleHeight);
-       me.frame.zoomedOutTitleBarPosition = me.zoomedOutTitleBarPosition;
-       me.frame.zoomedOutTitleBar = me.zoomedOutTitleBar;
-       me.frame.alpha = me.alpha;
-       me.addItem(me, me.frame, '0 0 0', '1 1 0', 1);
+       if(me.isTabRoot)
+       {
+               me.frame = NEW(BorderImage);
+               me.frame.configureBorderImage(me.frame, me.title, me.titleFontSize, me.color, me.backgroundImage, me.borderLines * me.titleHeight);
+               me.frame.zoomedOutTitleBarPosition = me.zoomedOutTitleBarPosition;
+               me.frame.zoomedOutTitleBar = me.zoomedOutTitleBar;
+               me.frame.alpha = me.alpha;
+               me.addItem(me, me.frame, '0 0 0', '1 1 0', 1);
+       }
 
        if (!me.titleFontSize)
                me.titleHeight = 0; // no title bar
@@ -155,7 +158,7 @@ void Dialog_configureDialog(entity me)
 
        me.fill(me);
 
-       if(me.closable && me.borderLines > 0)
+       if(me.isTabRoot && me.closable && me.borderLines > 0)
        {
                entity closebutton;
                closebutton = me.closeButton = me.frame.closeButton = NEW(Button);
index 044c9e3..f7c17fa 100644 (file)
@@ -6,11 +6,14 @@ CLASS(ListBox, Item)
        METHOD(ListBox, configureListBox, void(entity, float, float))
        METHOD(ListBox, draw, void(entity))
        METHOD(ListBox, keyDown, float(entity, float, float, float))
+       METHOD(ListBox, mouseMove, float(entity, vector))
        METHOD(ListBox, mousePress, float(entity, vector))
        METHOD(ListBox, mouseDrag, float(entity, vector))
        METHOD(ListBox, mouseRelease, float(entity, vector))
        METHOD(ListBox, focusLeave, void(entity))
        ATTRIB(ListBox, focusable, float, 1)
+       ATTRIB(ListBox, focusedItem, int, -1)
+       ATTRIB(ListBox, focusedItemAlpha, float, 0.3)
        ATTRIB(ListBox, allowFocusSound, float, 1)
        ATTRIB(ListBox, selectedItem, int, 0)
        ATTRIB(ListBox, size, vector, '0 0 0')
@@ -42,7 +45,7 @@ CLASS(ListBox, Item)
        ATTRIB(ListBox, lastClickedItem, float, -1)
        ATTRIB(ListBox, lastClickedTime, float, 0)
 
-       METHOD(ListBox, drawListBoxItem, void(entity, float, vector, float)) // item number, width/height, selected
+       METHOD(ListBox, drawListBoxItem, void(entity, int, vector, bool, bool)) // item number, width/height, isSelected, isFocused
        METHOD(ListBox, clickListBoxItem, void(entity, float, vector)) // item number, relative clickpos
        METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)) // item number, relative clickpos
        METHOD(ListBox, setSelected, void(entity, float))
@@ -178,6 +181,22 @@ float ListBox_keyDown(entity me, float key, float ascii, float shift)
                return 0;
        return 1;
 }
+float ListBox_mouseMove(entity me, vector pos)
+{
+       if(pos_x < 0) return 0;
+       if(pos_y < 0) return 0;
+       if(pos_x >= 1) return 0;
+       if(pos_y >= 1) return 0;
+       if(pos_x < 1 - me.controlWidth)
+       {
+               float x;
+               x = me.focusedItem;
+               me.focusedItem = me.getItemAtPos(me, me.scrollPos + pos.y);
+               if(x != me.focusedItem)
+                       me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED;
+       }
+       return 1;
+}
 float ListBox_mouseDrag(entity me, vector pos)
 {
        float hit;
@@ -288,6 +307,7 @@ void ListBox_focusLeave(entity me)
        // by a mouse click on an item of the list
        // for example showing a dialog on right click
        me.pressed = 0;
+       me.focusedItem = -1;
 }
 void ListBox_updateControlTopBottom(entity me)
 {
@@ -369,6 +389,7 @@ void ListBox_draw(entity me)
        draw_SetClip();
        oldshift = draw_shift;
        oldscale = draw_scale;
+
        float y;
        i = me.getItemAtPos(me, me.scrollPos);
        y = me.getItemStart(me, i) - me.scrollPos;
@@ -378,7 +399,7 @@ void ListBox_draw(entity me)
                vector relSize = eX * (1 - me.controlWidth) + eY * me.getItemHeight(me, i);
                absSize = boxToGlobalSize(relSize, me.size);
                draw_scale = boxToGlobalSize(relSize, oldscale);
-               me.drawListBoxItem(me, i, absSize, (me.selectedItem == i));
+               me.drawListBoxItem(me, i, absSize, (me.selectedItem == i), (me.focusedItem == i));
                y += relSize.y;
        }
        draw_ClearClip();
@@ -398,8 +419,8 @@ void ListBox_doubleClickListBoxItem(entity me, float i, vector where)
        // template method
 }
 
-void ListBox_drawListBoxItem(entity me, float i, vector absSize, float selected)
+void ListBox_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
-       draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize.x) + eY * (8 / absSize.y), (selected ? '0 1 0' : '1 1 1'), 1, 0);
+       draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize.x) + eY * (8 / absSize.y), (isSelected ? '0 1 0' : '1 1 1'), 1, 0);
 }
 #endif
index 669e08f..d8a3ede 100644 (file)
@@ -2,7 +2,8 @@
 #include "oo/classes.qc"
 #include "xonotic/util.qh"
 
-#include "../common/weapons/weapons.qh"
+#include "../common/items/all.qh"
+#include "../common/weapons/all.qh"
 #include "../common/mapinfo.qh"
 
 ///////////////////////////////////////////////
@@ -80,6 +81,7 @@ void m_init()
 
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+       CALL_ACCUMULATED_FUNCTION(RegisterItems);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
 
        RegisterSLCategories();
index 5c74f0d..28b87ab 100644 (file)
@@ -1,71 +1,11 @@
 #ifndef BASE_H
 #define BASE_H
 
+#include "../../common/oo.qh"
+
 #include "../../common/util.qh"
 #include "../../dpdefs/keycodes.qh"
 
-#define NULL (null_entity)
 #define world NULL
 
-.string classname;
-.string vtblname;
-.entity vtblbase;
-entity spawnVtbl(entity this, entity base)
-{
-       entity vtbl = spawn();
-       copyentity(this, vtbl);
-       vtbl.vtblname = vtbl.classname;
-       vtbl.classname = "vtbl";
-       vtbl.vtblbase = base ? base : vtbl; // Top level objects use vtbl as base
-       return vtbl;
-}
-
-entity Object_vtbl;
-entity spawnObject(entity this, entity)
-{
-       this = spawn();
-       this.classname = "Object";
-       if (!Object_vtbl) Object_vtbl = spawnVtbl(this, null_entity);
-       return this;
-}
-
-// Classes have a `spawn##cname(entity, entity)` constructor
-// The parameters are used as locals for [[accumulate]]
-
-// Macro to hide this implementation detail
-#define NEW(cname) (spawn##cname(null_entity, null_entity))
-
-#define CLASS(cname, base)                                          \
-entity spawn##cname(entity this, entity basevtbl) {                 \
-    this = NEW(base); basevtbl = base##_vtbl;                       \
-}
-
-#define METHOD(cname, name, prototype)                              \
-prototype cname##_##name;                                           \
-.prototype name;                                                    \
-[[accumulate]] entity spawn##cname(entity this, entity basevtbl) {  \
-    this.name = cname##_##name;                                     \
-}
-
-#define ATTRIB(cname, name, type, val)                              \
-.type name;                                                         \
-[[accumulate]] entity spawn##cname(entity this, entity basevtbl) {  \
-    this.name = val;                                                \
-}
-
-#define ATTRIBARRAY(cname, name, type, cnt)                         \
-.type name[cnt];
-
-#define ENDCLASS(cname)                                             \
-.bool instanceOf##cname;                                            \
-entity cname##_vtbl;                                                \
-[[last]] entity spawn##cname(entity this, entity basevtbl) {        \
-    this.instanceOf##cname = true;                                  \
-    this.classname = #cname;                                        \
-    if (!cname##_vtbl) cname##_vtbl = spawnVtbl(this, basevtbl);    \
-    return this;                                                    \
-}
-
-#define SUPER(cname) (cname##_vtbl.vtblbase)
-
-#endif
\ No newline at end of file
+#endif
index abfb303..2315616 100644 (file)
@@ -9,7 +9,7 @@ oo/classes.qc
 draw.qc
 menu.qc
 
-command/commands.qc
+command/all.qc
 
 xonotic/util.qc
 
@@ -21,8 +21,10 @@ xonotic/util.qc
 ../common/urllib.qc
 ../common/util.qc
 
-../common/monsters/monsters.qc
+../common/items/all.qc
 
-../common/weapons/weapons.qc // TODO
+../common/monsters/all.qc
+
+../common/weapons/all.qc // TODO
 
 ../warpzonelib/mathlib.qc
index ee0e76f..bf29683 100644 (file)
@@ -144,9 +144,6 @@ SKINBEGIN
        SKINFLOAT(ROWS_CREDITS, 20);
        SKINFLOAT(WIDTH_CREDITS, 0.5);
 
-       // item: crosshair button
-       SKINSTRING(GFX_CROSSHAIRBUTTON, "crosshairbutton");
-
        // item: cvar list
        SKINFLOAT(ALPHA_CVARLIST_SAVED, 1);
        SKINFLOAT(ALPHA_CVARLIST_TEMPORARY, 0.7);
@@ -191,6 +188,9 @@ SKINBEGIN
        SKINFLOAT(ALPHA_LISTBOX_WAITING, 0.5);
        SKINVECTOR(COLOR_LISTBOX_BACKGROUND, '0 0 0');
        SKINFLOAT(ALPHA_LISTBOX_BACKGROUND, 0.5);
+       SKINVECTOR(COLOR_LISTBOX_FOCUSED, '0 0 1');
+       SKINFLOAT(ALPHA_LISTBOX_FOCUSED, 0.7);
+       SKINFLOAT(FADEALPHA_LISTBOX_FOCUSED, 0.3);
 
        // item: map list
        SKINVECTOR(COLOR_MAPLIST_TITLE, '1 1 1');
@@ -211,11 +211,13 @@ SKINBEGIN
        SKINVECTOR(COLOR_MODELTITLE, '1 1 1');
        SKINFLOAT(ALPHA_MODELTITLE, 1);
 
-       // item: player name editor
+       // item: special character picker
        SKINVECTOR(COLOR_CHARMAP_CHAR, '1 1 1');
        SKINFLOAT(ALPHA_CHARMAP_CHAR, 1);
-       SKINVECTOR(COLOR_CHARMAP_FOCUS, '0 0 1');
-       SKINFLOAT(ALPHA_CHARMAP_FOCUS, 0.5);
+
+       // item: crosshair picker
+       SKINVECTOR(COLOR_CROSSHAIRPICKER_CROSSHAIR, '1 1 1');
+       SKINFLOAT(ALPHA_CROSSHAIRPICKER_CROSSHAIR, 1);
 
        // item: radio button
        SKINSTRING(GFX_RADIOBUTTON, "radiobutton");
index 826a0b4..e30c038 100644 (file)
@@ -7,7 +7,7 @@ CLASS(XonoticCampaignList, XonoticListBox)
        METHOD(XonoticCampaignList, configureXonoticCampaignList, void(entity))
        ATTRIB(XonoticCampaignList, rowsPerItem, float, 10)
        METHOD(XonoticCampaignList, draw, void(entity))
-       METHOD(XonoticCampaignList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticCampaignList, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticCampaignList, doubleClickListBoxItem, void(entity, float, vector))
        METHOD(XonoticCampaignList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticCampaignList, setSelected, void(entity, float))
@@ -239,7 +239,7 @@ void XonoticCampaignList_doubleClickListBoxItem(entity me, float i, vector where
 {
        CampaignList_LoadMap(me, me);
 }
-void XonoticCampaignList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected)
+void XonoticCampaignList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        vector theColor;
@@ -265,6 +265,11 @@ void XonoticCampaignList_drawListBoxItem(entity me, int i, vector absSize, bool
 
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        if(draw_PictureSize(strcat("/maps/", campaign_mapname[i])) == '0 0 0')
                draw_Picture(me.columnPreviewOrigin * eX, "nopreview_map", me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
index d6bc524..747d1f0 100644 (file)
@@ -1,34 +1,27 @@
 #ifndef CHARMAP_H
 #define CHARMAP_H
-#include "../item.qc"
-CLASS(XonoticCharmap, Item)
+#include "picker.qc"
+CLASS(XonoticCharmap, XonoticPicker)
        METHOD(XonoticCharmap, configureXonoticCharmap, void(entity, entity))
-       METHOD(XonoticCharmap, mousePress, float(entity, vector))
-       METHOD(XonoticCharmap, mouseRelease, float(entity, vector))
-       METHOD(XonoticCharmap, mouseMove, float(entity, vector))
-       METHOD(XonoticCharmap, mouseDrag, float(entity, vector))
-       METHOD(XonoticCharmap, keyDown, float(entity, float, float, float))
        METHOD(XonoticCharmap, focusLeave, void(entity))
        METHOD(XonoticCharmap, resizeNotify, void(entity, vector, vector, vector, vector))
-       METHOD(XonoticCharmap, draw, void(entity))
-       ATTRIB(XonoticCharmap, focusable, float, 1)
-
-       METHOD(XonoticCharmap, moveFocus, void(entity, vector, vector))
-       METHOD(XonoticCharmap, enterChar, void(entity))
+       METHOD(XonoticCharmap, keyDown, float(entity, float, float, float))
        ATTRIB(XonoticCharmap, inputBox, entity, NULL)
        ATTRIB(XonoticCharmap, realFontSize, vector, '0 0 0')
-       ATTRIB(XonoticCharmap, realCellSize, vector, '0 0 0')
-       ATTRIB(XonoticCharmap, focusedCell, vector, '-1 -1 0')
-       ATTRIB(XonoticCharmap, previouslyFocusedCell, vector, '-1 -1 0')
+
+       ATTRIB(XonoticCharmap, rows, float, 10)
+       ATTRIB(XonoticCharmap, columns, float, 14)
+
+       METHOD(XonoticCharmap, cellSelect, void(entity, vector))
+       METHOD(XonoticCharmap, cellIsValid, bool(entity, vector))
+       METHOD(XonoticCharmap, cellDraw, void(entity, vector, vector))
+       METHOD(XonoticCharmap, charOffset, vector)
 ENDCLASS(XonoticCharmap)
 entity makeXonoticCharmap(entity controlledInputBox);
 #endif
 
 #ifdef IMPLEMENTATION
 
-const float CHARMAP_COLS = 14;
-const float CHARMAP_ROWS = 10;
-
 string CHARMAP =
        "★◆■▮▰▬◣◤◥◢◀▲▶▼"
        "🌍🌎🌏🚀🌌👽🔫⌖❇❈←↑→↓"
@@ -46,11 +39,11 @@ string CHARMAP =
        "\xEE\x83\x8F\xEE\x83\x90\xEE\x83\x91\xEE\x83\x92\xEE\x83\x93\xEE\x83\x94\xEE\x83\x95"
        "\xEE\x83\x96\xEE\x83\x97\xEE\x83\x98\xEE\x83\x99\xEE\x83\x9A\xEE\x81\x9B\xEE\x81\x9D";
 
-string charmap_cellToChar(vector cell)
+string charmap_cellToChar(entity me, vector cell)
 {
-       string character = substring(CHARMAP, cell.y * CHARMAP_COLS + cell.x, 1);
+       string character = substring(CHARMAP, cell.y * me.columns + cell.x, 1);
 
-       if (character != " ")
+       if(character != " ")
                return character;
        else
                return "";
@@ -67,7 +60,7 @@ entity makeXonoticCharmap(entity controlledInputBox)
 void XonoticCharmap_configureXonoticCharmap(entity me, entity controlledInputBox)
 {
        me.inputBox = controlledInputBox;
-       me.realCellSize = eX / CHARMAP_COLS + eY / CHARMAP_ROWS;
+       me.configureXonoticPicker(me);
 }
 
 void XonoticCharmap_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
@@ -90,153 +83,38 @@ void XonoticCharmap_resizeNotify(entity me, vector relOrigin, vector relSize, ve
 
        if(me.realFontSize.x > maxFontWidth || me.realFontSize.y > maxFontHeight)
                me.realFontSize = eX * maxFontWidth + eY * maxFontHeight;
-}
-
-float XonoticCharmap_mouseMove(entity me, vector coords)
-{
-       me.focusedCell_x = floor(coords.x * CHARMAP_COLS);
-       me.focusedCell_y = floor(coords.y * CHARMAP_ROWS);
 
-       if(me.focusedCell.x < 0 || me.focusedCell.y < 0 ||
-          me.focusedCell.x >= CHARMAP_COLS || me.focusedCell.y >= CHARMAP_ROWS)
-       {
-               me.focusedCell = '-1 -1 0';
-               return 0;
-       }
-
-       return 1;
+       me.charOffset = eX * me.realCellSize.x / 2 + eY * ((me.realCellSize.y - me.realFontSize.y) / 2);
 }
 
-float XonoticCharmap_mouseDrag(entity me, vector coords)
-{
-       return me.mouseMove(me, coords);
-}
-
-float XonoticCharmap_mousePress(entity me, vector coords)
-{
-       me.mouseMove(me, coords);
-
-       if(me.focusedCell.x >= 0)
-       {
-               me.pressed = 1;
-               me.previouslyFocusedCell = me.focusedCell;
-       }
-
-       return 1;
-}
-
-float XonoticCharmap_mouseRelease(entity me, vector coords)
+float XonoticCharmap_keyDown(entity me, float key, float ascii, float shift)
 {
-       if(!me.pressed)
-               return 0;
-
-       me.mouseMove(me, coords);
-
-       if(me.focusedCell == me.previouslyFocusedCell)
-               me.enterChar(me);
-
-       me.pressed = 0;
-       return 1;
+       if(SUPER(XonoticCharmap).keyDown(me, key, ascii, shift))
+               return 1;
+       return me.inputBox.keyDown(me.inputBox, key, ascii, shift);
 }
 
-float XonoticCharmap_keyDown(entity me, float key, float ascii, float shift)
+void XonoticCharmap_cellSelect(entity me, vector cell)
 {
-       switch(key)
-       {
-               case K_LEFTARROW:
-               case K_KP_LEFTARROW:
-                       me.moveFocus(me, me.focusedCell, '-1 0 0');
-                       return 1;
-               case K_RIGHTARROW:
-               case K_KP_RIGHTARROW:
-                       me.moveFocus(me, me.focusedCell, '1 0 0');
-                       return 1;
-               case K_UPARROW:
-               case K_KP_UPARROW:
-                       me.moveFocus(me, me.focusedCell, '0 -1 0');
-                       return 1;
-               case K_DOWNARROW:
-               case K_KP_DOWNARROW:
-                       me.moveFocus(me, me.focusedCell, '0 1 0');
-                       return 1;
-               case K_HOME:
-               case K_KP_HOME:
-                       me.focusedCell = '0 0 0';
-                       return 1;
-               case K_END:
-               case K_KP_END:
-                       me.focusedCell_x = CHARMAP_COLS - 1;
-                       me.focusedCell_y = CHARMAP_ROWS - 1;
-                       return 1;
-               case K_ENTER:
-               case K_KP_ENTER:
-               case K_INS:
-               case K_KP_INS:
-                       me.enterChar(me);
-                       return 1;
-               default:
-                       return me.inputBox.keyDown(me.inputBox, key, ascii, shift);
-       }
+       string character = charmap_cellToChar(me, cell);
+       if(character != "")
+               me.inputBox.enterText(me.inputBox, character);
 }
 
-void XonoticCharmap_moveFocus(entity me, vector initialCell, vector step)
+bool XonoticCharmap_cellIsValid(entity me, vector cell)
 {
-       me.focusedCell_x = mod(me.focusedCell.x + step.x + CHARMAP_COLS, CHARMAP_COLS);
-       me.focusedCell_y = mod(me.focusedCell.y + step.y + CHARMAP_ROWS, CHARMAP_ROWS);
-
-       if(me.focusedCell != initialCell) // Recursion break
-               if(charmap_cellToChar(me.focusedCell) == "")
-                       me.moveFocus(me, initialCell, step);
+       if(charmap_cellToChar(me, cell) == "")
+               return false;
+       return true;
 }
 
-void XonoticCharmap_enterChar(entity me)
+void XonoticCharmap_cellDraw(entity me, vector cell, vector cellPos)
 {
-       string character = charmap_cellToChar(me.focusedCell);
-       if(character != "")
-               me.inputBox.enterText(me.inputBox, character);
+       draw_CenterText(cellPos + me.charOffset, charmap_cellToChar(me, cell), me.realFontSize, SKINCOLOR_CHARMAP_CHAR, SKINALPHA_CHARMAP_CHAR, 0);
 }
 
 void XonoticCharmap_focusLeave(entity me)
 {
        me.inputBox.saveCvars(me.inputBox);
 }
-
-void XonoticCharmap_draw(entity me)
-{
-       string character;
-       vector cell, cellPos, charPos;
-       cell = '0 0 0';
-       cellPos = '0 0 0';
-       charPos = '0 0 0';
-
-       float CHAR_OFFSET_X = me.realCellSize.x / 2;
-       float CHAR_OFFSET_Y = (me.realCellSize.y - me.realFontSize.y) / 2;
-
-       for(cell_y = 0; cell.y < CHARMAP_ROWS; ++cell.y)
-       {
-               charPos_y = cell.y / CHARMAP_ROWS + CHAR_OFFSET_Y;
-               for(cell_x = 0; cell.x < CHARMAP_COLS; ++cell.x)
-               {
-                       character = charmap_cellToChar(cell);
-
-                       if(character == "")
-                               continue;
-
-                       // Draw focused cell
-                       if(cell == me.focusedCell && me.focused)
-                       {
-                               if(!me.pressed || me.focusedCell == me.previouslyFocusedCell)
-                               {
-                                       cellPos_x = mod(me.focusedCell.x, CHARMAP_COLS) / CHARMAP_COLS;
-                                       cellPos_y = mod(me.focusedCell.y, CHARMAP_ROWS) / CHARMAP_ROWS;
-                                       draw_Fill(cellPos, me.realCellSize, SKINCOLOR_CHARMAP_FOCUS, SKINALPHA_CHARMAP_FOCUS);
-                               }
-                       }
-
-                       // Draw character
-                       charPos_x = cell.x / CHARMAP_COLS + CHAR_OFFSET_X;
-                       draw_CenterText(charPos, character, me.realFontSize, SKINCOLOR_CHARMAP_CHAR, SKINALPHA_CHARMAP_CHAR, 0);
-               }
-       }
-}
 #endif
index d7e17f5..57320a0 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticCreditsList, XonoticListBox)
        METHOD(XonoticCreditsList, configureXonoticCreditsList, void(entity))
        ATTRIB(XonoticCreditsList, rowsPerItem, float, 1)
        METHOD(XonoticCreditsList, draw, void(entity))
-       METHOD(XonoticCreditsList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticCreditsList, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticCreditsList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticCreditsList, keyDown, float(entity, float, float, float))
        METHOD(XonoticCreditsList, destroy, void(entity))
@@ -59,7 +59,7 @@ void XonoticCreditsList_resizeNotify(entity me, vector relOrigin, vector relSize
        me.realFontSize_x = me.fontSize / (absSize.x * (1 - me.controlWidth));
        me.realUpperMargin = 0.5 * (1 - me.realFontSize.y);
 }
-void XonoticCreditsList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticCreditsList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        // layout: Ping, Credits name, Map name, NP, TP, MP
        string s;
diff --git a/qcsrc/menu/xonotic/crosshairbutton.qc b/qcsrc/menu/xonotic/crosshairbutton.qc
deleted file mode 100644 (file)
index 466846f..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-#ifndef CROSSHAIRBUTTON_H
-#define CROSSHAIRBUTTON_H
-#include "../item/radiobutton.qc"
-CLASS(XonoticCrosshairButton, RadioButton)
-       METHOD(XonoticCrosshairButton, configureXonoticCrosshairButton, void(entity, float, float))
-       METHOD(XonoticCrosshairButton, setChecked, void(entity, float))
-       METHOD(XonoticCrosshairButton, draw, void(entity))
-       ATTRIB(XonoticCrosshairButton, fontSize, float, SKINFONTSIZE_NORMAL)
-       ATTRIB(XonoticCrosshairButton, image, string, SKINGFX_CROSSHAIRBUTTON)
-
-       ATTRIB(XonoticCrosshairButton, useDownAsChecked, float, 1)
-       ATTRIB(XonoticCrosshairButton, src3, string, string_null)
-       ATTRIB(XonoticCrosshairButton, src4, string, string_null)
-
-       ATTRIB(XonoticCrosshairButton, cvarName, string, string_null)
-       ATTRIB(XonoticCrosshairButton, cvarValueFloat, float, 0)
-       METHOD(XonoticCrosshairButton, loadCvars, void(entity))
-       METHOD(XonoticCrosshairButton, saveCvars, void(entity))
-ENDCLASS(XonoticCrosshairButton)
-entity makeXonoticCrosshairButton(float, float);
-#endif
-
-#ifdef IMPLEMENTATION
-entity makeXonoticCrosshairButton(float theGroup, float theCrosshair)
-{
-       entity me;
-       me = NEW(XonoticCrosshairButton);
-       me.configureXonoticCrosshairButton(me, theGroup, theCrosshair);
-       return me;
-}
-void XonoticCrosshairButton_configureXonoticCrosshairButton(entity me, float theGroup, float theCrosshair)
-{
-       me.cvarName = "crosshair";
-       me.cvarValueFloat = theCrosshair;
-       me.loadCvars(me);
-       me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0);
-       me.srcMulti = 1;
-       if(me.cvarValueFloat == -1)
-               me.src3 = strzone(strcat("/gfx/crosshair", cvar_string("crosshair")));
-       else
-               me.src3 = strzone(strcat("/gfx/crosshair", ftos(me.cvarValueFloat)));
-       me.src4 = "/gfx/crosshairdot";
-}
-void XonoticCrosshairButton_setChecked(entity me, float val)
-{
-       if(me.cvarValueFloat != -1) // preview shouldn't work as a button
-       if(val != me.checked)
-       {
-               me.checked = val;
-               me.saveCvars(me);
-       }
-}
-void XonoticCrosshairButton_loadCvars(entity me)
-{
-       if (!me.cvarName)
-               return;
-
-       me.checked = (cvar(me.cvarName) == me.cvarValueFloat);
-}
-void XonoticCrosshairButton_saveCvars(entity me)
-{
-       if (!me.cvarName)
-               return;
-
-       if(me.checked)
-               cvar_set(me.cvarName, ftos(me.cvarValueFloat));
-       // TODO on an apply button, read _cl_color and execute the color command for it
-}
-void XonoticCrosshairButton_draw(entity me)
-{
-       vector sz, rgb;
-       float a;
-
-
-       if(me.cvarValueFloat == -1)
-       {
-               rgb = stov(cvar_string("crosshair_color"));
-               a = cvar("crosshair_alpha");
-       }
-       else if(me.checked || me.focused)
-       {
-               a = 1;
-               rgb = '1 1 1';
-       }
-       else
-       {
-               a = me.disabledAlpha;
-               rgb = '1 1 1';
-       }
-
-       if(me.cvarValueFloat == -1) // update the preview if this is the preview button
-       {
-               if(me.src3)
-                       strunzone(me.src3);
-               me.src3 = strzone(strcat("/gfx/crosshair", cvar_string("crosshair")));
-               me.focused = 1;
-               me.checked = 0;
-       }
-
-       SUPER(XonoticCrosshairButton).draw(me);
-
-       sz = draw_PictureSize(me.src3);
-       sz = globalToBoxSize(sz, me.size);
-       if(me.cvarValueFloat == -1)
-       {
-               sz = sz * cvar("crosshair_size"); // (6 * '1 1 0' + ...) * 0.08 here to make visible size changes happen also at bigger sizes
-               /*
-               if(sz_x > 0.95)
-                       sz = sz * (0.95 / sz_x);
-               if(sz_y > 0.95)
-                       sz = sz * (0.95 / sz_y);
-               */
-       }
-       else // show the crosshair picker at full size
-       {
-               sz = sz * (0.95 / sz.x);
-               if(sz.y > 0.95)
-                       sz = sz * (0.95 / sz.y);
-       }
-
-       draw_Picture('0.5 0.5 0' - 0.5 * sz, me.src3, sz, rgb, a);
-       if(cvar("crosshair_dot"))
-       {
-               if(cvar("crosshair_dot_color_custom") && (cvar_string("crosshair_dot_color") != "0"))
-                       rgb = stov(cvar_string("crosshair_dot_color"));
-
-               draw_Picture('0.5 0.5 0' - 0.5 * sz * cvar("crosshair_dot_size"), me.src4, sz * cvar("crosshair_dot_size"), rgb, a * cvar("crosshair_dot_alpha"));
-       }
-}
-#endif
diff --git a/qcsrc/menu/xonotic/crosshairpicker.qc b/qcsrc/menu/xonotic/crosshairpicker.qc
new file mode 100644 (file)
index 0000000..8922e7f
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef CROSSHAIRPICKER_H
+#define CROSSHAIRPICKER_H
+#include "picker.qc"
+CLASS(XonoticCrosshairPicker, XonoticPicker)
+       METHOD(XonoticCrosshairPicker, configureXonoticCrosshairPicker, void(entity))
+
+       ATTRIB(XonoticCrosshairPicker, rows, float, 3)
+       ATTRIB(XonoticCrosshairPicker, columns, float, 12)
+
+       METHOD(XonoticCrosshairPicker, cellSelect, void(entity, vector))
+       METHOD(XonoticCrosshairPicker, cellIsValid, bool(entity, vector))
+       METHOD(XonoticCrosshairPicker, cellDraw, void(entity, vector, vector))
+ENDCLASS(XonoticCrosshairPicker)
+entity makeXonoticCrosshairPicker();
+#endif
+
+#ifdef IMPLEMENTATION
+
+string crosshairpicker_cellToCrosshair(entity me, vector cell)
+{
+       if(cell.x < 0 || cell.x >= me.columns || cell.y < 0 || cell.y >= me.rows)
+               return "";
+       return ftos(31 + cell.y * me.columns + cell.x);
+}
+
+vector crosshairpicker_crosshairToCell(entity me, string crosshair_str)
+{
+       float crosshair = stof(crosshair_str) - 31;
+       if(crosshair - floor(crosshair) > 0)
+               return '-1 -1 0';
+       return mod(crosshair, me.columns) * eX + floor(crosshair / me.columns) * eY;
+}
+
+entity makeXonoticCrosshairPicker()
+{
+       entity me;
+       me = NEW(XonoticCrosshairPicker);
+       me.configureXonoticCrosshairPicker(me);
+       return me;
+}
+
+void XonoticCrosshairPicker_configureXonoticCrosshairPicker(entity me)
+{
+       me.configureXonoticPicker(me);
+       SUPER(XonoticCrosshairPicker).cellSelect(me, crosshairpicker_crosshairToCell(me, cvar_string("crosshair")));
+}
+
+void XonoticCrosshairPicker_cellSelect(entity me, vector cell)
+{
+       cvar_set("crosshair", crosshairpicker_cellToCrosshair(me, me.focusedCell));
+       SUPER(XonoticCrosshairPicker).cellSelect(me, me.focusedCell);
+}
+
+bool XonoticCrosshairPicker_cellIsValid(entity me, vector cell)
+{
+       if(crosshairpicker_cellToCrosshair(me, cell) == "")
+               return false;
+       return true;
+}
+
+void XonoticCrosshairPicker_cellDraw(entity me, vector cell, vector cellPos)
+{
+       vector sz;
+       string cross = strcat("/gfx/crosshair", crosshairpicker_cellToCrosshair(me, cell));
+       sz = draw_PictureSize(cross);
+       sz = globalToBoxSize(sz, me.size);
+
+       float ar = sz.x / sz.y;
+       sz.x = me.realCellSize.x;
+       sz.y = sz.x / ar;
+       sz = sz * 0.95;
+
+       vector crosshairPos = cellPos + 0.5 * me.realCellSize;
+       draw_Picture(crosshairPos - 0.5 * sz, cross, sz, SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
+
+       if(cvar("crosshair_dot"))
+               draw_Picture(crosshairPos - 0.5 * sz * cvar("crosshair_dot_size"), "/gfx/crosshairdot", sz * cvar("crosshair_dot_size"), SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
+}
+#endif
diff --git a/qcsrc/menu/xonotic/crosshairpreview.qc b/qcsrc/menu/xonotic/crosshairpreview.qc
new file mode 100644 (file)
index 0000000..f8de857
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef CROSSHAIRPREVIEW_H
+#define CROSSHAIRPREVIEW_H
+#include "../item.qc"
+CLASS(XonoticCrosshairPreview, Item)
+       METHOD(XonoticCrosshairPreview, configureXonoticCrosshairPreview, void(entity))
+       METHOD(XonoticCrosshairPreview, draw, void(entity))
+       ATTRIB(XonoticCrosshairPreview, src, string, string_null)
+       ATTRIB(XonoticCrosshairPreview, src2, string, string_null)
+       ATTRIB(XonoticCrosshairPreview, disabled, float, 0)
+       ATTRIB(XonoticCrosshairPreview, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticCrosshairPreview)
+entity makeXonoticCrosshairPreview();
+#endif
+
+#ifdef IMPLEMENTATION
+entity makeXonoticCrosshairPreview()
+{
+       entity me;
+       me = NEW(XonoticCrosshairPreview);
+       me.configureXonoticCrosshairPreview(me);
+       return me;
+}
+
+void XonoticCrosshairPreview_configureXonoticCrosshairPreview(entity me)
+{
+       me.src = strzone(strcat("/gfx/crosshair", cvar_string("crosshair")));
+       me.src2 = "/gfx/crosshairdot";
+}
+
+void XonoticCrosshairPreview_draw(entity me)
+{
+       float save;
+       save = draw_alpha;
+       if(me.disabled)
+               draw_alpha *= me.disabledAlpha;
+
+       vector sz, rgb;
+       float a;
+       rgb = stov(cvar_string("crosshair_color"));
+       a = cvar("crosshair_alpha");
+       if(me.src)
+               strunzone(me.src);
+       me.src = strzone(strcat("/gfx/crosshair", cvar_string("crosshair")));
+
+       sz = draw_PictureSize(me.src);
+       sz = globalToBoxSize(sz, me.size);
+       sz = sz * cvar("crosshair_size");
+
+       draw_Picture('0.5 0.5 0' - 0.5 * sz, me.src, sz, rgb, a);
+       if(cvar("crosshair_dot"))
+       {
+               if(cvar("crosshair_dot_color_custom") && (cvar_string("crosshair_dot_color") != "0"))
+                       rgb = stov(cvar_string("crosshair_dot_color"));
+
+               draw_Picture('0.5 0.5 0' - 0.5 * sz * cvar("crosshair_dot_size"), me.src2, sz * cvar("crosshair_dot_size"), rgb, a * cvar("crosshair_dot_alpha"));
+       }
+
+       draw_alpha = save;
+
+       SUPER(XonoticCrosshairPreview).draw(me);
+}
+#endif
index 44520c1..9a95ed1 100644 (file)
@@ -4,7 +4,7 @@
 CLASS(XonoticCvarList, XonoticListBox)
        METHOD(XonoticCvarList, configureXonoticCvarList, void(entity))
        ATTRIB(XonoticCvarList, rowsPerItem, float, 1)
-       METHOD(XonoticCvarList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticCvarList, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticCvarList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticCvarList, keyDown, float(entity, float, float, float))
 
@@ -154,7 +154,7 @@ void XonoticCvarList_resizeNotify(entity me, vector relOrigin, vector relSize, v
 
        me.setSelected(me, me.selectedItem);
 }
-void XonoticCvarList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticCvarList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string k, v, d;
        float t;
@@ -166,6 +166,11 @@ void XonoticCvarList_drawListBoxItem(entity me, float i, vector absSize, float i
 
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        k = bufstr_get(me.handle, i);
 
index 4f759f6..f46ee40 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticDemoList, XonoticListBox)
        METHOD(XonoticDemoList, configureXonoticDemoList, void(entity))
        ATTRIB(XonoticDemoList, rowsPerItem, float, 1)
        METHOD(XonoticDemoList, resizeNotify, void(entity, vector, vector, vector, vector))
-       METHOD(XonoticDemoList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticDemoList, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticDemoList, getDemos, void(entity))
        METHOD(XonoticDemoList, startDemo, void(entity))
        METHOD(XonoticDemoList, timeDemo, void(entity))
@@ -135,11 +135,16 @@ void XonoticDemoList_resizeNotify(entity me, vector relOrigin, vector relSize, v
        me.columnNameSize = 1 - 2 * me.realFontSize.x;
 }
 
-void XonoticDemoList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticDemoList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s;
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        s = me.demoName(me,i);
        s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
index 6aedde7..64cfbd9 100644 (file)
@@ -19,9 +19,6 @@ void XonoticMultiplayerDialog_fill(entity me)
        me.TR(me);
                me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Servers"), makeXonoticServerListTab()));
                me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Create"), makeXonoticServerCreateTab()));
-               //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Demos"), makeXonoticDemoBrowserTab()));
-               //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Screenshots"), makeXonoticScreenshotBrowserTab()));
-               //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Players"), makeXonoticDemoBrowserTab()));
                me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Media"), makeXonoticMediaTab()));
                me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Profile"), makeXonoticProfileTab()));
 
index 13a8e31..e56f2ee 100644 (file)
@@ -5,7 +5,6 @@ CLASS(XonoticServerCreateTab, XonoticTab)
        METHOD(XonoticServerCreateTab, fill, void(entity))
        METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity))
        METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity))
-       ATTRIB(XonoticServerCreateTab, title, string, _("Create"))
        ATTRIB(XonoticServerCreateTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticServerCreateTab, rows, float, 23)
        ATTRIB(XonoticServerCreateTab, columns, float, 6.2) // added extra .2 for center space
index 4494452..8ab5296 100644 (file)
@@ -1,4 +1,4 @@
-#include "../../common/weapons/weapons.qh"
+#include "../../common/weapons/all.qh"
 
 #ifndef DIALOG_MULTIPLAYER_CREATE_MUTATORS_H
 #define DIALOG_MULTIPLAYER_CREATE_MUTATORS_H
index 2b2354c..a4e480e 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticServerListTab, XonoticTab)
        METHOD(XonoticServerListTab, fill, void(entity))
-       ATTRIB(XonoticServerListTab, title, string, _("Join"))
        ATTRIB(XonoticServerListTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticServerListTab, rows, float, 23)
        ATTRIB(XonoticServerListTab, columns, float, 6.5)
index f6b5e02..03ffd0f 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticMediaTab, XonoticTab)
        METHOD(XonoticMediaTab, fill, void(entity))
-       ATTRIB(XonoticMediaTab, title, string, _("Media"))
        ATTRIB(XonoticMediaTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticMediaTab, rows, float, 23)
        ATTRIB(XonoticMediaTab, columns, float, 3)
index 8ae5ae0..788aa53 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticDemoBrowserTab, XonoticTab)
        METHOD(XonoticDemoBrowserTab, fill, void(entity))
-       ATTRIB(XonoticDemoBrowserTab, title, string, _("Demo"))
        ATTRIB(XonoticDemoBrowserTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticDemoBrowserTab, rows, float, 21)
        ATTRIB(XonoticDemoBrowserTab, columns, float, 6.5)
index 8fc33c1..6c0791f 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticMusicPlayerTab, XonoticTab)
        METHOD(XonoticMusicPlayerTab, fill, void(entity))
-       ATTRIB(XonoticMusicPlayerTab, title, string, _("Music"))
        ATTRIB(XonoticMusicPlayerTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticMusicPlayerTab, rows, float, 21)
        ATTRIB(XonoticMusicPlayerTab, columns, float, 6.5)
index 36832a9..c6526f2 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticScreenshotBrowserTab, XonoticTab)
        METHOD(XonoticScreenshotBrowserTab, fill, void(entity))
-       ATTRIB(XonoticScreenshotBrowserTab, title, string, "Screenshot")
        ATTRIB(XonoticScreenshotBrowserTab, intendedWidth, float, 1)
        ATTRIB(XonoticScreenshotBrowserTab, rows, float, 21)
        ATTRIB(XonoticScreenshotBrowserTab, columns, float, 6.5)
index f9615d2..9faf428 100644 (file)
@@ -4,7 +4,6 @@
 CLASS(XonoticProfileTab, XonoticTab)
        METHOD(XonoticProfileTab, fill, void(entity))
        METHOD(XonoticProfileTab, draw, void(entity))
-       ATTRIB(XonoticProfileTab, title, string, _("Profile"))
        ATTRIB(XonoticProfileTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticProfileTab, rows, float, 23)
        ATTRIB(XonoticProfileTab, columns, float, 6.1) // added extra .2 for center space
index 528d950..af8fadd 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticAudioSettingsTab, XonoticTab)
        METHOD(XonoticAudioSettingsTab, fill, void(entity))
-       ATTRIB(XonoticAudioSettingsTab, title, string, _("Audio"))
        ATTRIB(XonoticAudioSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticAudioSettingsTab, rows, float, 15.5)
        ATTRIB(XonoticAudioSettingsTab, columns, float, 6.2) // added extra .2 for center space
index a49e176..d064650 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticEffectsSettingsTab, XonoticTab)
        METHOD(XonoticEffectsSettingsTab, fill, void(entity))
-       ATTRIB(XonoticEffectsSettingsTab, title, string, _("Effects"))
        ATTRIB(XonoticEffectsSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticEffectsSettingsTab, rows, float, 15.5)
        ATTRIB(XonoticEffectsSettingsTab, columns, float, 6.2) // added extra .2 for center space
index e8fd42d..5b14b7b 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticGameSettingsTab, XonoticTab)
        METHOD(XonoticGameSettingsTab, fill, void(entity))
-       ATTRIB(XonoticGameSettingsTab, title, string, _("Game"))
        ATTRIB(XonoticGameSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticGameSettingsTab, rows, float, 15.5)
        ATTRIB(XonoticGameSettingsTab, columns, float, 6.5)
index bda4fad..cee4bd5 100644 (file)
@@ -2,10 +2,8 @@
 #define DIALOG_SETTINGS_GAME_CROSSHAIR_H
 #include "tab.qc"
 CLASS(XonoticGameCrosshairSettingsTab, XonoticTab)
-       //METHOD(XonoticGameCrosshairSettingsTab, toString, string(entity))
        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)
@@ -29,7 +27,6 @@ entity makeXonoticGameCrosshairSettingsTab()
 void XonoticGameCrosshairSettingsTab_fill(entity me)
 {
        entity e;
-       float i;
 
        // crosshair_enabled: 0 = no crosshair options, 1 = no crosshair selection, but everything else enabled, 2 = all crosshair options enabled
        // FIXME: In the future, perhaps make one global crosshair_type cvar which has 0 for disabled, 1 for custom, 2 for per weapon, etc?
@@ -42,26 +39,12 @@ void XonoticGameCrosshairSettingsTab_fill(entity me)
                me.TD(me, 1, 1, e = makeXonoticRadioButton(3, "crosshair_enabled", "2", _("Custom")));
        me.TR(me);
                me.TDempty(me, 0.1);
-               for(i = 31; i <= 42; ++i) {
-                       me.TDNoMargin(me, 1, 2 / 12, e = makeXonoticCrosshairButton(4, i), '1 1 0');
-                               setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
-               }
-               // show a larger preview of the selected crosshair
-               me.TDempty(me, 0.1);
-               me.TDNoMargin(me, 3, 0.8, e = makeXonoticCrosshairButton(7, -1), '1 1 0'); // crosshair -1 makes this a preview
+               me.TD(me, 3, 2, e = makeXonoticCrosshairPicker());
+                       setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
+               me.TD(me, 3, 0.9, e = makeXonoticCrosshairPreview());
                        setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
        me.TR(me);
-               me.TDempty(me, 0.1);
-               for(i = 43; i <= 54; ++i) {
-                       me.TDNoMargin(me, 1, 2 / 12, e = makeXonoticCrosshairButton(4, i), '1 1 0');
-                               setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
-               }
        me.TR(me);
-               me.TDempty(me, 0.1);
-               for(i = 55; i <= 66; ++i) {
-                       me.TDNoMargin(me, 1, 2 / 12, e = makeXonoticCrosshairButton(4, i), '1 1 0');
-                               setDependentAND(e, "crosshair_per_weapon", 0, 0, "crosshair_enabled", 1, 2);
-               }
        me.TR(me);
                me.TDempty(me, 0.1);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Crosshair size:")));
index 751eaa6..941daa7 100644 (file)
@@ -2,10 +2,8 @@
 #define DIALOG_SETTINGS_GAME_HUD_H
 #include "tab.qc"
 CLASS(XonoticGameHUDSettingsTab, XonoticTab)
-       //METHOD(XonoticGameHUDSettingsTab, toString, string(entity))
        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)
index eccd938..d52a102 100644 (file)
@@ -2,10 +2,8 @@
 #define DIALOG_SETTINGS_GAME_MESSAGES_H
 #include "tab.qc"
 CLASS(XonoticGameMessageSettingsTab, XonoticTab)
-       //METHOD(XonoticGameWeaponsSettingsTab, toString, string(entity))
        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)
index 32955ba..db3e408 100644 (file)
@@ -2,10 +2,8 @@
 #define DIALOG_SETTINGS_GAME_MODEL_H
 #include "tab.qc"
 CLASS(XonoticGameModelSettingsTab, XonoticTab)
-       //METHOD(XonoticGameModelSettingsTab, toString, string(entity))
        METHOD(XonoticGameModelSettingsTab, fill, void(entity))
        METHOD(XonoticGameModelSettingsTab, showNotify, void(entity))
-       ATTRIB(XonoticGameModelSettingsTab, title, string, _("Model"))
        ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticGameModelSettingsTab, rows, float, 13)
        ATTRIB(XonoticGameModelSettingsTab, columns, float, 5)
index 4daef47..40a526d 100644 (file)
@@ -2,10 +2,8 @@
 #define DIALOG_SETTINGS_GAME_VIEW_H
 #include "tab.qc"
 CLASS(XonoticGameViewSettingsTab, XonoticTab)
-       //METHOD(XonoticGameCrosshairSettingsTab, toString, string(entity))
        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)
index 573f139..c59a962 100644 (file)
@@ -2,10 +2,8 @@
 #define DIALOG_SETTINGS_GAME_WEAPONS_H
 #include "tab.qc"
 CLASS(XonoticGameWeaponsSettingsTab, XonoticTab)
-       //METHOD(XonoticGameWeaponsSettingsTab, toString, string(entity))
        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)
index 752aade..f8e53c0 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticInputSettingsTab, XonoticTab)
        METHOD(XonoticInputSettingsTab, fill, void(entity))
-       ATTRIB(XonoticInputSettingsTab, title, string, _("Input"))
        ATTRIB(XonoticInputSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticInputSettingsTab, rows, float, 15.5)
        ATTRIB(XonoticInputSettingsTab, columns, float, 6.2) // added extra .2 for center space
index 95f218b..79e1961 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticMiscSettingsTab, XonoticTab)
        METHOD(XonoticMiscSettingsTab, fill, void(entity))
-       ATTRIB(XonoticMiscSettingsTab, title, string, _("Misc"))
        ATTRIB(XonoticMiscSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticMiscSettingsTab, rows, float, 15.5)
        ATTRIB(XonoticMiscSettingsTab, columns, float, 6.2)
index e9ad109..35246ae 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticUserSettingsTab, XonoticTab)
        METHOD(XonoticUserSettingsTab, fill, void(entity))
-       ATTRIB(XonoticUserSettingsTab, title, string, _("User"))
        ATTRIB(XonoticUserSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticUserSettingsTab, rows, float, 15.5)
        ATTRIB(XonoticUserSettingsTab, columns, float, 6)
index 9b77e40..61a93f6 100644 (file)
@@ -3,7 +3,6 @@
 #include "tab.qc"
 CLASS(XonoticVideoSettingsTab, XonoticTab)
        METHOD(XonoticVideoSettingsTab, fill, void(entity))
-       ATTRIB(XonoticVideoSettingsTab, title, string, _("Video"))
        ATTRIB(XonoticVideoSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticVideoSettingsTab, rows, float, 15.5)
        ATTRIB(XonoticVideoSettingsTab, columns, float, 6.2) // added extra .2 for center space
index d8dbc88..26845f0 100644 (file)
@@ -4,7 +4,7 @@
 CLASS(XonoticGametypeList, XonoticListBox)
        METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity))
        ATTRIB(XonoticGametypeList, rowsPerItem, float, 2)
-       METHOD(XonoticGametypeList, drawListBoxItem, void(entity, float, vector, float))
+       METHOD(XonoticGametypeList, drawListBoxItem, void(entity, int, vector, bool, bool))
        METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector))
        METHOD(XonoticGametypeList, setSelected, void(entity, float))
        METHOD(XonoticGametypeList, loadCvars, void(entity))
@@ -78,12 +78,17 @@ void XonoticGametypeList_saveCvars(entity me)
                owner.gameTypeChangeNotify(owner);
        }
 }
-void XonoticGametypeList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
+void XonoticGametypeList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s1, s2;
 
        if(isSelected)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+       else if(isFocused)
+       {
+               me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+               draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
+       }
 
        draw_Picture(me.columnIconOrigin * eX, GameType_GetIcon(i), me.colu