seta hud_panel_healtharmor_progressbar_gfx_damage 5 "show damage effect when damaged at least by this amount; 0 disables the effect"
seta hud_panel_healtharmor_progressbar_gfx_lowhealth 40 "health progressbar blinks when health is lower than this amount"
+seta hud_panel_timer_increment "0" "show elapsed time instead of remaining time"
+
seta hud_panel_engineinfo_framecounter_exponentialmovingaverage 1 "use an averaging method for calculating fps instead of counting frametime like engine does"
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"
+seta hud_panel_physics_speed_unit "1" "speed unit (1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots)"
seta hud_panel_itemstime_progressbar_maxtime "30" "when left time is at least this amount, the status bar is full"
seta hud_panel_itemstime_hidespawned "1" "if 1 hide an item from the panel when all the occurrences of it are available again; if 2 hide it when at least one occurrence is available again"
seta hud_panel_timer_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
seta hud_panel_timer_bg_border "" "if set to something else than \"\" = override default size of border around the background"
seta hud_panel_timer_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
-seta hud_panel_timer_increment "" "show elapsed time instead of remaining time"
seta hud_panel_radar "" "enable/disable this panel, 2 = also enable in non-teambased gamemodes"
seta hud_panel_radar_pos "" "position of this base of the panel"
seta hud_panel_physics_acceleration_vertical "" "include the acceleration on the Z-axis"
seta hud_panel_physics_text "" "show text in panel (2 = only for speed; 3 = only for acceleration)"
seta hud_panel_physics_text_scale "" "scale text height by this factor"
-seta hud_panel_physics_speed_unit "" "speed unit (1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots)"
seta hud_panel_physics_speed_unit_show "" "also show speed unit"
seta hud_panel_physics_speed_max "" "speed progressbar gets filled up completely by this value (in qu/s)"
seta hud_panel_physics_speed_vertical "" "include the speed on the Z-axis"
if [ x"$mode" = x"txt" ]; then
{
- echo "en English \"English\""
+ item=`grep "^en " languages.txt`
+ echo "$item"
for X in common.*.po; do
[ -f "$X" ] || continue
if [ -n "$language" ]; then
if [ "$p" -lt 50 ]; then
continue
fi
- item="$l $l \"$l (0%)\""
+ item="$l $l \"$l\" 0%"
fi
- printf "%s\n" "$item" | sed -e "s/([0-9][0-9]*%)/($p%)/"
+ printf "%s\n" "$item" | sed -e "s/[0-9][0-9]*%/$p%/"
done
} | tr '"' '\t' | sort -k3 | tr '\t' '"'
fi
set g_ctf_oneflag 1 "Allow oneflag CTF mode on maps that support it"
set g_ctf_oneflag_reverse 0 "apply reverse mode to oneflag CTF (take flag to enemy bases to cap), overrides g_ctf_reverse only in oneflag, g_ctf_reverse still affects oneflag"
set g_ctf_flag_return 1 "auto return the flag to base when touched by a teammate"
+set g_ctf_flag_return_carrying 0 "(manual return mode) auto return the flag to base if touched by a flag carrier"
set g_ctf_flag_return_carried_radius 100 "allow flags to be returned by carrier if base is within this radius"
set g_ctf_flag_return_time 15
set g_ctf_flag_return_dropped 100
seta hud_dock_alpha "1"
seta hud_progressbar_alpha "0.600000"
+seta hud_progressbar_strength_color "1 0.39 0"
+seta hud_progressbar_superweapons_color "0.77 0.67 0"
+seta hud_progressbar_shield_color "0.36 1 0.07"
seta hud_progressbar_health_color "0.83 0.12 0"
seta hud_progressbar_armor_color "0.28 0.8 0"
seta hud_progressbar_fuel_color "0.77 0.67 0"
-seta hud_progressbar_strength_color "1 0.39 0"
-seta hud_progressbar_shield_color "0.36 1 0.07"
-seta hud_progressbar_superweapons_color "0.77 0.67 0"
seta hud_progressbar_nexball_color "0.2 0.65 0.93"
seta hud_progressbar_speed_color "0.77 0.67 0"
seta hud_progressbar_acceleration_color "0.2 0.65 0.93"
seta hud_configure_grid_xsize "0.005000"
seta hud_configure_grid_ysize "0.005000"
-seta hud_panel_weapons 1
+seta hud_panel_weapons "1"
seta hud_panel_weapons_pos "0.965000 0.125000"
seta hud_panel_weapons_size "0.035000 0.770000"
seta hud_panel_weapons_bg "border_default_east"
seta hud_panel_weapons_bg_padding "0"
seta hud_panel_weapons_accuracy "0"
seta hud_panel_weapons_label "1"
-seta hud_panel_weapons_label_scale "0.3"
+seta hud_panel_weapons_label_scale "0.300000"
seta hud_panel_weapons_complainbubble "1"
seta hud_panel_weapons_complainbubble_padding "0"
seta hud_panel_weapons_complainbubble_time "0"
seta hud_panel_weapons_timeout_speed_in "0.25"
seta hud_panel_weapons_timeout_speed_out "0.75"
seta hud_panel_weapons_onlyowned "1"
-seta hud_panel_weapons_noncurrent_alpha "0.8"
-seta hud_panel_weapons_noncurrent_scale "0.9"
+seta hud_panel_weapons_noncurrent_alpha "0.800000"
+seta hud_panel_weapons_noncurrent_scale "0.900000"
-seta hud_panel_ammo 1
+seta hud_panel_ammo "1"
seta hud_panel_ammo_pos "0.315000 0.865000"
seta hud_panel_ammo_size "0.370000 0.060000"
seta hud_panel_ammo_bg "border_tab_south"
seta hud_panel_ammo_bg_border ""
seta hud_panel_ammo_bg_padding "4"
seta hud_panel_ammo_onlycurrent "0"
-seta hud_panel_ammo_noncurrent_alpha "0.6"
-seta hud_panel_ammo_noncurrent_scale "0.4"
+seta hud_panel_ammo_noncurrent_alpha "0.600000"
+seta hud_panel_ammo_noncurrent_scale "0.400000"
seta hud_panel_ammo_iconalign "0"
seta hud_panel_ammo_progressbar "0"
seta hud_panel_ammo_progressbar_name "progressbar"
seta hud_panel_ammo_progressbar_xoffset "0"
seta hud_panel_ammo_text "1"
-seta hud_panel_powerups 1
+seta hud_panel_powerups "1"
seta hud_panel_powerups_pos "0.325000 0.815000"
seta hud_panel_powerups_size "0.350000 0.055000"
seta hud_panel_powerups_bg "border_shadow_south"
seta hud_panel_powerups_progressbar "1"
seta hud_panel_powerups_text "1"
-seta hud_panel_healtharmor 1
+seta hud_panel_healtharmor "1"
seta hud_panel_healtharmor_pos "0.300000 0.925000"
seta hud_panel_healtharmor_size "0.400000 0.070000"
seta hud_panel_healtharmor_bg "border_default_south"
seta hud_panel_healtharmor_progressbar_gfx_smooth "2"
seta hud_panel_healtharmor_text "1"
-seta hud_panel_notify 1
+seta hud_panel_notify "1"
seta hud_panel_notify_pos "0.730000 0.800000"
seta hud_panel_notify_size "0.265000 0.200000"
seta hud_panel_notify_bg "0"
seta hud_panel_notify_fadetime "3"
seta hud_panel_notify_icon_aspect "1"
-seta hud_panel_timer 1
+seta hud_panel_timer "1"
seta hud_panel_timer_pos "0.456000 0"
seta hud_panel_timer_size "0.088000 0.030000"
seta hud_panel_timer_bg "border_plain_north"
seta hud_panel_timer_bg_alpha ""
seta hud_panel_timer_bg_border ""
seta hud_panel_timer_bg_padding "0"
-seta hud_panel_timer_increment "0"
-seta hud_panel_radar 1
+seta hud_panel_radar "1"
seta hud_panel_radar_pos "0 0"
seta hud_panel_radar_size "0.200000 0.250000"
seta hud_panel_radar_bg "border_corner_northwest"
seta hud_panel_radar_maximized_rotation "1"
seta hud_panel_radar_maximized_zoommode "3"
-seta hud_panel_score 1
+seta hud_panel_score "1"
seta hud_panel_score_pos "0.880000 0"
seta hud_panel_score_size "0.120000 0.080000"
seta hud_panel_score_bg "border_corner_northeast"
seta hud_panel_score_bg_padding "1"
seta hud_panel_score_rankings "1"
-seta hud_panel_racetimer 1
+seta hud_panel_racetimer "1"
seta hud_panel_racetimer_pos "0.360000 0.110000"
seta hud_panel_racetimer_size "0.280000 0.090000"
seta hud_panel_racetimer_bg "0"
seta hud_panel_racetimer_bg_border ""
seta hud_panel_racetimer_bg_padding ""
-seta hud_panel_vote 1
+seta hud_panel_vote "1"
seta hud_panel_vote_pos "0.740000 0.690000"
seta hud_panel_vote_size "0.190000 0.090000"
seta hud_panel_vote_bg " "
seta hud_panel_vote_bg_padding ""
seta hud_panel_vote_alreadyvoted_alpha "0.700000"
-seta hud_panel_modicons 1
+seta hud_panel_modicons "1"
seta hud_panel_modicons_pos "0.370000 0.030000"
seta hud_panel_modicons_size "0.260000 0.07000"
seta hud_panel_modicons_bg "border_fading_north"
seta hud_panel_modicons_dom_layout "1"
seta hud_panel_modicons_freezetag_layout "1"
-seta hud_panel_pressedkeys 1
+seta hud_panel_pressedkeys "1"
seta hud_panel_pressedkeys_pos "0.445000 0.710000"
seta hud_panel_pressedkeys_size "0.110000 0.090000"
seta hud_panel_pressedkeys_bg " "
seta hud_panel_pressedkeys_aspect "1.600000"
seta hud_panel_pressedkeys_attack "0"
-seta hud_panel_chat 1
+seta hud_panel_chat "1"
seta hud_panel_chat_pos "0.010000 0.700000"
seta hud_panel_chat_size "0.460000 0.190000"
seta hud_panel_chat_bg "0"
seta hud_panel_chat_bg_border ""
seta hud_panel_chat_bg_padding ""
-seta hud_panel_engineinfo 0
+seta hud_panel_engineinfo "0"
seta hud_panel_engineinfo_pos "0.930000 0.970000"
seta hud_panel_engineinfo_size "0.070000 0.030000"
seta hud_panel_engineinfo_bg "0"
seta hud_panel_engineinfo_framecounter_time "0.1"
seta hud_panel_engineinfo_framecounter_decimals "0"
-seta hud_panel_infomessages 1
+seta hud_panel_infomessages "1"
seta hud_panel_infomessages_pos "0.720000 0.100000"
seta hud_panel_infomessages_size "0.280000 0.080000"
seta hud_panel_infomessages_bg "0"
seta hud_panel_infomessages_bg_padding "0"
seta hud_panel_infomessages_flip "1"
-seta hud_panel_physics 3
+seta hud_panel_physics "3"
seta hud_panel_physics_pos "0.410000 0.625000"
seta hud_panel_physics_size "0.180000 0.080000"
seta hud_panel_physics_bg "0"
seta hud_panel_physics_bg_alpha "0.700000"
seta hud_panel_physics_bg_border ""
seta hud_panel_physics_bg_padding ""
-seta hud_panel_physics_speed_unit "1"
seta hud_panel_physics_speed_unit_show "1"
seta hud_panel_physics_speed_max "1800"
seta hud_panel_physics_speed_vertical "0"
seta hud_panel_physics_text "1"
seta hud_panel_physics_text_scale "0.7"
-seta hud_panel_centerprint 1
+seta hud_panel_centerprint "1"
seta hud_panel_centerprint_pos "0.175000 0.220000"
seta hud_panel_centerprint_size "0.650000 0.220000"
seta hud_panel_centerprint_bg "0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
-seta hud_panel_mapvote 1
-seta hud_panel_mapvote_pos "0 0"
-seta hud_panel_mapvote_size "1 1"
-seta hud_panel_mapvote_bg "border_default"
-seta hud_panel_mapvote_bg_color ""
-seta hud_panel_mapvote_bg_color_team ""
-seta hud_panel_mapvote_bg_alpha ""
-seta hud_panel_mapvote_bg_border ""
-seta hud_panel_mapvote_bg_padding ""
-
-seta hud_panel_itemstime 2
-seta hud_panel_itemstime_pos "0.030000 0.260000"
-seta hud_panel_itemstime_size "0.070000 0.230000"
-seta hud_panel_itemstime_bg "border_itemstime"
-seta hud_panel_itemstime_bg_color ""
-seta hud_panel_itemstime_bg_color_team ""
-seta hud_panel_itemstime_bg_alpha ""
-seta hud_panel_itemstime_bg_border ""
-seta hud_panel_itemstime_bg_padding ""
-seta hud_panel_itemstime_iconalign "0"
-seta hud_panel_itemstime_progressbar "0"
-seta hud_panel_itemstime_progressbar_name "progressbar"
-seta hud_panel_itemstime_progressbar_reduced "0"
-seta hud_panel_itemstime_text "1"
-seta hud_panel_itemstime_ratio "2"
-seta hud_panel_itemstime_dynamicsize "1"
-
seta hud_panel_minigameboard "1"
seta hud_panel_minigameboard_pos "0.22 0.15"
seta hud_panel_minigameboard_size "0.50 0.60"
seta hud_panel_minigamemenu_bg_border ""
seta hud_panel_minigamemenu_bg_padding ""
-seta hud_panel_quickmenu 1
+seta hud_panel_mapvote "1"
+seta hud_panel_mapvote_pos "0 0"
+seta hud_panel_mapvote_size "1 1"
+seta hud_panel_mapvote_bg "border_default"
+seta hud_panel_mapvote_bg_color ""
+seta hud_panel_mapvote_bg_color_team ""
+seta hud_panel_mapvote_bg_alpha ""
+seta hud_panel_mapvote_bg_border ""
+seta hud_panel_mapvote_bg_padding ""
+
+seta hud_panel_itemstime "2"
+seta hud_panel_itemstime_pos "0.030000 0.260000"
+seta hud_panel_itemstime_size "0.070000 0.230000"
+seta hud_panel_itemstime_bg "border_itemstime"
+seta hud_panel_itemstime_bg_color ""
+seta hud_panel_itemstime_bg_color_team ""
+seta hud_panel_itemstime_bg_alpha ""
+seta hud_panel_itemstime_bg_border ""
+seta hud_panel_itemstime_bg_padding ""
+seta hud_panel_itemstime_iconalign "0"
+seta hud_panel_itemstime_progressbar "0"
+seta hud_panel_itemstime_progressbar_name "progressbar"
+seta hud_panel_itemstime_progressbar_reduced "0"
+seta hud_panel_itemstime_text "1"
+seta hud_panel_itemstime_ratio "2"
+seta hud_panel_itemstime_dynamicsize "1"
+
+seta hud_panel_quickmenu "1"
seta hud_panel_quickmenu_pos "0.600000 0.445000"
seta hud_panel_quickmenu_size "0.220000 0.240000"
seta hud_panel_quickmenu_bg ""
seta hud_configure_grid_xsize "0.010000"
seta hud_configure_grid_ysize "0.010000"
-seta hud_panel_weapons 1
+seta hud_panel_weapons "1"
seta hud_panel_weapons_pos "0.930000 0.170000"
seta hud_panel_weapons_size "0.070000 0.650000"
seta hud_panel_weapons_bg "border_small_weapons"
seta hud_panel_weapons_bg_padding "4"
seta hud_panel_weapons_accuracy "1"
seta hud_panel_weapons_label "1"
-seta hud_panel_weapons_label_scale "0.5"
+seta hud_panel_weapons_label_scale "0.500000"
seta hud_panel_weapons_complainbubble "1"
seta hud_panel_weapons_complainbubble_padding "-1"
seta hud_panel_weapons_complainbubble_time "0"
seta hud_panel_weapons_noncurrent_alpha "1"
seta hud_panel_weapons_noncurrent_scale "1"
-seta hud_panel_ammo 1
+seta hud_panel_ammo "1"
seta hud_panel_ammo_pos "0.330000 0.960000"
seta hud_panel_ammo_size "0.350000 0.040000"
seta hud_panel_ammo_bg ""
seta hud_panel_ammo_bg_border ""
seta hud_panel_ammo_bg_padding ""
seta hud_panel_ammo_onlycurrent "0"
-seta hud_panel_ammo_noncurrent_alpha "0.7"
+seta hud_panel_ammo_noncurrent_alpha "0.700000"
seta hud_panel_ammo_noncurrent_scale "1"
seta hud_panel_ammo_iconalign "0"
seta hud_panel_ammo_progressbar "0"
seta hud_panel_ammo_progressbar_xoffset "0"
seta hud_panel_ammo_text "1"
-seta hud_panel_powerups 1
+seta hud_panel_powerups "1"
seta hud_panel_powerups_pos "0.360000 0.850000"
seta hud_panel_powerups_size "0.290000 0.030000"
seta hud_panel_powerups_bg "border_small_powerups"
seta hud_panel_powerups_progressbar "1"
seta hud_panel_powerups_text "1"
-seta hud_panel_healtharmor 1
+seta hud_panel_healtharmor "1"
seta hud_panel_healtharmor_pos "0.320000 0.910000"
seta hud_panel_healtharmor_size "0.370000 0.060000"
seta hud_panel_healtharmor_bg "border_small_healtharmor"
seta hud_panel_healtharmor_progressbar_gfx_smooth "2"
seta hud_panel_healtharmor_text "1"
-seta hud_panel_notify 1
+seta hud_panel_notify "1"
seta hud_panel_notify_pos "0.710000 0.800000"
seta hud_panel_notify_size "0.290000 0.190000"
seta hud_panel_notify_bg "0"
seta hud_panel_notify_fadetime "3"
seta hud_panel_notify_icon_aspect "2"
-seta hud_panel_timer 1
+seta hud_panel_timer "1"
seta hud_panel_timer_pos "0.800000 0.040000"
seta hud_panel_timer_size "0.070000 0.040000"
seta hud_panel_timer_bg "border_small_timer"
seta hud_panel_timer_bg_alpha ""
seta hud_panel_timer_bg_border ""
seta hud_panel_timer_bg_padding "0"
-seta hud_panel_timer_increment "0"
-seta hud_panel_radar 2
+seta hud_panel_radar "2"
seta hud_panel_radar_pos "0 0"
seta hud_panel_radar_size "0.200000 0.240000"
seta hud_panel_radar_bg "border_small_radar"
seta hud_panel_radar_maximized_rotation "1"
seta hud_panel_radar_maximized_zoommode "3"
-seta hud_panel_score 1
+seta hud_panel_score "1"
seta hud_panel_score_pos "0.890000 0.030000"
seta hud_panel_score_size "0.100000 0.050000"
seta hud_panel_score_bg "border_small_score"
seta hud_panel_score_bg_padding "0"
seta hud_panel_score_rankings "1"
-seta hud_panel_racetimer 1
+seta hud_panel_racetimer "1"
seta hud_panel_racetimer_pos "0.360000 0.110000"
seta hud_panel_racetimer_size "0.280000 0.090000"
seta hud_panel_racetimer_bg "0"
seta hud_panel_racetimer_bg_border ""
seta hud_panel_racetimer_bg_padding ""
-seta hud_panel_vote 1
+seta hud_panel_vote "1"
seta hud_panel_vote_pos "0.720000 0.670000"
seta hud_panel_vote_size "0.190000 0.090000"
seta hud_panel_vote_bg "border_vote"
seta hud_panel_vote_bg_padding ""
seta hud_panel_vote_alreadyvoted_alpha "0.500000"
-seta hud_panel_modicons 1
+seta hud_panel_modicons "1"
seta hud_panel_modicons_pos "0.410000 0"
seta hud_panel_modicons_size "0.180000 0.080000"
seta hud_panel_modicons_bg "border_small_modicons"
seta hud_panel_modicons_dom_layout "1"
seta hud_panel_modicons_freezetag_layout "1"
-seta hud_panel_pressedkeys 1
+seta hud_panel_pressedkeys "1"
seta hud_panel_pressedkeys_pos "0.450000 0.720000"
seta hud_panel_pressedkeys_size "0.110000 0.090000"
seta hud_panel_pressedkeys_bg "0"
seta hud_panel_pressedkeys_aspect "1.600000"
seta hud_panel_pressedkeys_attack "0"
-seta hud_panel_chat 1
+seta hud_panel_chat "1"
seta hud_panel_chat_pos "0.010000 0.700000"
seta hud_panel_chat_size "0.460000 0.190000"
seta hud_panel_chat_bg "0"
seta hud_panel_chat_bg_border ""
seta hud_panel_chat_bg_padding ""
-seta hud_panel_engineinfo 0
+seta hud_panel_engineinfo "0"
seta hud_panel_engineinfo_pos "0.930000 0.970000"
seta hud_panel_engineinfo_size "0.070000 0.030000"
seta hud_panel_engineinfo_bg "0"
seta hud_panel_engineinfo_framecounter_time "0.1"
seta hud_panel_engineinfo_framecounter_decimals "0"
-seta hud_panel_infomessages 1
+seta hud_panel_infomessages "1"
seta hud_panel_infomessages_pos "0.720000 0.100000"
seta hud_panel_infomessages_size "0.280000 0.080000"
seta hud_panel_infomessages_bg "0"
seta hud_panel_infomessages_bg_padding "0"
seta hud_panel_infomessages_flip "1"
-seta hud_panel_physics 3
+seta hud_panel_physics "3"
seta hud_panel_physics_pos "0.420000 0.620000"
seta hud_panel_physics_size "0.170000 0.080000"
seta hud_panel_physics_bg ""
seta hud_panel_physics_bg_alpha ""
seta hud_panel_physics_bg_border ""
seta hud_panel_physics_bg_padding ""
-seta hud_panel_physics_speed_unit "3"
seta hud_panel_physics_speed_unit_show "1"
seta hud_panel_physics_speed_max "1800"
seta hud_panel_physics_speed_vertical "0"
seta hud_panel_physics_text "1"
seta hud_panel_physics_text_scale "0.7"
-seta hud_panel_centerprint 1
+seta hud_panel_centerprint "1"
seta hud_panel_centerprint_pos "0.175000 0.220000"
seta hud_panel_centerprint_size "0.650000 0.220000"
seta hud_panel_centerprint_bg "0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
-seta hud_panel_mapvote 1
-seta hud_panel_mapvote_pos "0 0"
-seta hud_panel_mapvote_size "1 1"
-seta hud_panel_mapvote_bg "0"
-seta hud_panel_mapvote_bg_color ""
-seta hud_panel_mapvote_bg_color_team ""
-seta hud_panel_mapvote_bg_alpha ""
-seta hud_panel_mapvote_bg_border ""
-seta hud_panel_mapvote_bg_padding ""
-
-seta hud_panel_itemstime 2
-seta hud_panel_itemstime_pos "0.030000 0.260000"
-seta hud_panel_itemstime_size "0.070000 0.230000"
-seta hud_panel_itemstime_bg "border_itemstime"
-seta hud_panel_itemstime_bg_color ""
-seta hud_panel_itemstime_bg_color_team ""
-seta hud_panel_itemstime_bg_alpha ""
-seta hud_panel_itemstime_bg_border ""
-seta hud_panel_itemstime_bg_padding ""
-seta hud_panel_itemstime_iconalign "0"
-seta hud_panel_itemstime_progressbar "0"
-seta hud_panel_itemstime_progressbar_name "progressbar"
-seta hud_panel_itemstime_progressbar_reduced "0"
-seta hud_panel_itemstime_text "1"
-seta hud_panel_itemstime_ratio "2"
-seta hud_panel_itemstime_dynamicsize "1"
-
seta hud_panel_minigameboard "1"
seta hud_panel_minigameboard_pos "0.22 0.15"
seta hud_panel_minigameboard_size "0.50 0.60"
seta hud_panel_minigamemenu_bg_border ""
seta hud_panel_minigamemenu_bg_padding ""
-seta hud_panel_quickmenu 1
+seta hud_panel_mapvote "1"
+seta hud_panel_mapvote_pos "0 0"
+seta hud_panel_mapvote_size "1 1"
+seta hud_panel_mapvote_bg "0"
+seta hud_panel_mapvote_bg_color ""
+seta hud_panel_mapvote_bg_color_team ""
+seta hud_panel_mapvote_bg_alpha ""
+seta hud_panel_mapvote_bg_border ""
+seta hud_panel_mapvote_bg_padding ""
+
+seta hud_panel_itemstime "2"
+seta hud_panel_itemstime_pos "0.030000 0.260000"
+seta hud_panel_itemstime_size "0.070000 0.230000"
+seta hud_panel_itemstime_bg "border_itemstime"
+seta hud_panel_itemstime_bg_color ""
+seta hud_panel_itemstime_bg_color_team ""
+seta hud_panel_itemstime_bg_alpha ""
+seta hud_panel_itemstime_bg_border ""
+seta hud_panel_itemstime_bg_padding ""
+seta hud_panel_itemstime_iconalign "0"
+seta hud_panel_itemstime_progressbar "0"
+seta hud_panel_itemstime_progressbar_name "progressbar"
+seta hud_panel_itemstime_progressbar_reduced "0"
+seta hud_panel_itemstime_text "1"
+seta hud_panel_itemstime_ratio "2"
+seta hud_panel_itemstime_dynamicsize "1"
+
+seta hud_panel_quickmenu "1"
seta hud_panel_quickmenu_pos "0.610000 0.450000"
seta hud_panel_quickmenu_size "0.200000 0.210000"
seta hud_panel_quickmenu_bg ""
seta hud_configure_grid_xsize "0.010000"
seta hud_configure_grid_ysize "0.010000"
-seta hud_panel_weapons 1
+seta hud_panel_weapons "1"
seta hud_panel_weapons_pos "0.350000 0.940000"
seta hud_panel_weapons_size "0.300000 0.060000"
seta hud_panel_weapons_bg ""
seta hud_panel_weapons_noncurrent_alpha "1"
seta hud_panel_weapons_noncurrent_scale "1"
-seta hud_panel_ammo 1
+seta hud_panel_ammo "1"
seta hud_panel_ammo_pos "0.650000 0.890000"
seta hud_panel_ammo_size "0.055000 0.110000"
seta hud_panel_ammo_bg ""
seta hud_panel_ammo_progressbar_xoffset "0"
seta hud_panel_ammo_text "1"
-seta hud_panel_powerups 1
+seta hud_panel_powerups "1"
seta hud_panel_powerups_pos "0.290000 0.890000"
seta hud_panel_powerups_size "0.055000 0.110000"
seta hud_panel_powerups_bg "0"
seta hud_panel_powerups_progressbar "1"
seta hud_panel_powerups_text "1"
-seta hud_panel_healtharmor 1
+seta hud_panel_healtharmor "1"
seta hud_panel_healtharmor_pos "0.350000 0.890000"
seta hud_panel_healtharmor_size "0.300000 0.050000"
seta hud_panel_healtharmor_bg ""
seta hud_panel_healtharmor_progressbar_gfx_smooth "2"
seta hud_panel_healtharmor_text "1"
-seta hud_panel_notify 1
+seta hud_panel_notify "1"
seta hud_panel_notify_pos "0 0"
seta hud_panel_notify_size "0.210000 0.260000"
seta hud_panel_notify_bg "0"
seta hud_panel_notify_fadetime "3"
seta hud_panel_notify_icon_aspect "2"
-seta hud_panel_timer 1
+seta hud_panel_timer "1"
seta hud_panel_timer_pos "0.435000 0"
seta hud_panel_timer_size "0.135000 0.060000"
seta hud_panel_timer_bg "0"
seta hud_panel_timer_bg_alpha ""
seta hud_panel_timer_bg_border ""
seta hud_panel_timer_bg_padding "0"
-seta hud_panel_timer_increment "0"
-seta hud_panel_radar 2
+seta hud_panel_radar "2"
seta hud_panel_radar_pos "0.810000 0"
seta hud_panel_radar_size "0.190000 0.250000"
seta hud_panel_radar_bg "border_radar"
seta hud_panel_radar_maximized_rotation "1"
seta hud_panel_radar_maximized_zoommode "3"
-seta hud_panel_score 1
+seta hud_panel_score "1"
seta hud_panel_score_pos "0.465000 0.045000"
seta hud_panel_score_size "0.090000 0.060000"
seta hud_panel_score_bg ""
seta hud_panel_score_bg_padding ""
seta hud_panel_score_rankings "1"
-seta hud_panel_racetimer 1
+seta hud_panel_racetimer "1"
seta hud_panel_racetimer_pos "0.360000 0.090000"
seta hud_panel_racetimer_size "0.280000 0.090000"
seta hud_panel_racetimer_bg "0"
seta hud_panel_racetimer_bg_border ""
seta hud_panel_racetimer_bg_padding ""
-seta hud_panel_vote 1
+seta hud_panel_vote "1"
seta hud_panel_vote_pos "0 0.890000"
seta hud_panel_vote_size "0.170000 0.110000"
seta hud_panel_vote_bg ""
seta hud_panel_vote_bg_padding ""
seta hud_panel_vote_alreadyvoted_alpha "0.800000"
-seta hud_panel_modicons 1
+seta hud_panel_modicons "1"
seta hud_panel_modicons_pos "0.560000 0"
seta hud_panel_modicons_size "0.050000 0.100000"
seta hud_panel_modicons_bg ""
seta hud_panel_modicons_dom_layout "1"
seta hud_panel_modicons_freezetag_layout "1"
-seta hud_panel_pressedkeys 1
+seta hud_panel_pressedkeys "1"
seta hud_panel_pressedkeys_pos "0.450000 0.650000"
seta hud_panel_pressedkeys_size "0.100000 0.110000"
seta hud_panel_pressedkeys_bg "0"
seta hud_panel_pressedkeys_aspect "1.600000"
seta hud_panel_pressedkeys_attack "0"
-seta hud_panel_chat 1
+seta hud_panel_chat "1"
seta hud_panel_chat_pos "0 0.775000"
seta hud_panel_chat_size "0.460000 0.110000"
seta hud_panel_chat_bg "0"
seta hud_panel_chat_bg_border ""
seta hud_panel_chat_bg_padding ""
-seta hud_panel_engineinfo 0
+seta hud_panel_engineinfo "0"
seta hud_panel_engineinfo_pos "0.910000 0.970000"
seta hud_panel_engineinfo_size "0.090000 0.030000"
seta hud_panel_engineinfo_bg "0"
seta hud_panel_engineinfo_framecounter_time "0.1"
seta hud_panel_engineinfo_framecounter_decimals "0"
-seta hud_panel_infomessages 1
+seta hud_panel_infomessages "1"
seta hud_panel_infomessages_pos "0.710000 0"
seta hud_panel_infomessages_size "0.290000 0.100000"
seta hud_panel_infomessages_bg "0"
seta hud_panel_infomessages_bg_padding "0"
seta hud_panel_infomessages_flip "1"
-seta hud_panel_physics 3
+seta hud_panel_physics "3"
seta hud_panel_physics_pos "0.440000 0.590000"
seta hud_panel_physics_size "0.120000 0.050000"
seta hud_panel_physics_bg ""
seta hud_panel_physics_bg_alpha ""
seta hud_panel_physics_bg_border ""
seta hud_panel_physics_bg_padding ""
-seta hud_panel_physics_speed_unit "3"
seta hud_panel_physics_speed_unit_show "1"
seta hud_panel_physics_speed_max "1800"
seta hud_panel_physics_speed_vertical "0"
seta hud_panel_physics_text "1"
seta hud_panel_physics_text_scale "0.7"
-seta hud_panel_centerprint 1
+seta hud_panel_centerprint "1"
seta hud_panel_centerprint_pos "0.175000 0.220000"
seta hud_panel_centerprint_size "0.650000 0.220000"
seta hud_panel_centerprint_bg "0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
-seta hud_panel_mapvote 1
-seta hud_panel_mapvote_pos "0 0"
-seta hud_panel_mapvote_size "1 1"
-seta hud_panel_mapvote_bg "0"
-seta hud_panel_mapvote_bg_color ""
-seta hud_panel_mapvote_bg_color_team ""
-seta hud_panel_mapvote_bg_alpha ""
-seta hud_panel_mapvote_bg_border ""
-seta hud_panel_mapvote_bg_padding ""
-
-seta hud_panel_itemstime 2
-seta hud_panel_itemstime_pos "0.000000 0.310000"
-seta hud_panel_itemstime_size "0.070000 0.180000"
-seta hud_panel_itemstime_bg ""
-seta hud_panel_itemstime_bg_color ""
-seta hud_panel_itemstime_bg_color_team ""
-seta hud_panel_itemstime_bg_alpha ""
-seta hud_panel_itemstime_bg_border ""
-seta hud_panel_itemstime_bg_padding ""
-seta hud_panel_itemstime_iconalign "0"
-seta hud_panel_itemstime_progressbar "0"
-seta hud_panel_itemstime_progressbar_name "progressbar"
-seta hud_panel_itemstime_progressbar_reduced "0"
-seta hud_panel_itemstime_text "1"
-seta hud_panel_itemstime_ratio "2"
-seta hud_panel_itemstime_dynamicsize "1"
-
seta hud_panel_minigameboard "1"
seta hud_panel_minigameboard_pos "0.22 0.15"
seta hud_panel_minigameboard_size "0.50 0.60"
seta hud_panel_minigamemenu_bg_border ""
seta hud_panel_minigamemenu_bg_padding ""
-seta hud_panel_quickmenu 1
+seta hud_panel_mapvote "1"
+seta hud_panel_mapvote_pos "0 0"
+seta hud_panel_mapvote_size "1 1"
+seta hud_panel_mapvote_bg "0"
+seta hud_panel_mapvote_bg_color ""
+seta hud_panel_mapvote_bg_color_team ""
+seta hud_panel_mapvote_bg_alpha ""
+seta hud_panel_mapvote_bg_border ""
+seta hud_panel_mapvote_bg_padding ""
+
+seta hud_panel_itemstime "2"
+seta hud_panel_itemstime_pos "0.000000 0.310000"
+seta hud_panel_itemstime_size "0.070000 0.180000"
+seta hud_panel_itemstime_bg ""
+seta hud_panel_itemstime_bg_color ""
+seta hud_panel_itemstime_bg_color_team ""
+seta hud_panel_itemstime_bg_alpha ""
+seta hud_panel_itemstime_bg_border ""
+seta hud_panel_itemstime_bg_padding ""
+seta hud_panel_itemstime_iconalign "0"
+seta hud_panel_itemstime_progressbar "0"
+seta hud_panel_itemstime_progressbar_name "progressbar"
+seta hud_panel_itemstime_progressbar_reduced "0"
+seta hud_panel_itemstime_text "1"
+seta hud_panel_itemstime_ratio "2"
+seta hud_panel_itemstime_dynamicsize "1"
+
+seta hud_panel_quickmenu "1"
seta hud_panel_quickmenu_pos "0.600000 0.460000"
seta hud_panel_quickmenu_size "0.190000 0.190000"
seta hud_panel_quickmenu_bg ""
seta hud_configure_grid_xsize "0.010000"
seta hud_configure_grid_ysize "0.010000"
-seta hud_panel_weapons 1
+seta hud_panel_weapons "1"
seta hud_panel_weapons_pos "0.350000 0.940000"
seta hud_panel_weapons_size "0.300000 0.060000"
seta hud_panel_weapons_bg ""
seta hud_panel_weapons_noncurrent_alpha "1"
seta hud_panel_weapons_noncurrent_scale "1"
-seta hud_panel_ammo 1
+seta hud_panel_ammo "1"
seta hud_panel_ammo_pos "0.450000 0.630000"
seta hud_panel_ammo_size "0.080000 0.040000"
seta hud_panel_ammo_bg ""
seta hud_panel_ammo_progressbar_xoffset "0.32"
seta hud_panel_ammo_text "1"
-seta hud_panel_powerups 1
+seta hud_panel_powerups "1"
seta hud_panel_powerups_pos "0.270000 0.940000"
seta hud_panel_powerups_size "0.080000 0.060000"
seta hud_panel_powerups_bg "0"
seta hud_panel_powerups_progressbar "1"
seta hud_panel_powerups_text "1"
-seta hud_panel_healtharmor 1
+seta hud_panel_healtharmor "1"
seta hud_panel_healtharmor_pos "0.350000 0.380000"
seta hud_panel_healtharmor_size "0.070000 0.240000"
seta hud_panel_healtharmor_bg "border_healtharmor"
seta hud_panel_healtharmor_progressbar_gfx_smooth "2"
seta hud_panel_healtharmor_text "0"
-seta hud_panel_notify 1
+seta hud_panel_notify "1"
seta hud_panel_notify_pos "0 0"
seta hud_panel_notify_size "0.210000 0.260000"
seta hud_panel_notify_bg "0"
seta hud_panel_notify_fadetime "3"
seta hud_panel_notify_icon_aspect "2"
-seta hud_panel_timer 1
+seta hud_panel_timer "1"
seta hud_panel_timer_pos "0.435000 0"
seta hud_panel_timer_size "0.135000 0.060000"
seta hud_panel_timer_bg "0"
seta hud_panel_timer_bg_alpha ""
seta hud_panel_timer_bg_border ""
seta hud_panel_timer_bg_padding "0"
-seta hud_panel_timer_increment "0"
-seta hud_panel_radar 2
+seta hud_panel_radar "2"
seta hud_panel_radar_pos "0.810000 0"
seta hud_panel_radar_size "0.190000 0.250000"
seta hud_panel_radar_bg "border_radar"
seta hud_panel_radar_maximized_rotation "1"
seta hud_panel_radar_maximized_zoommode "3"
-seta hud_panel_score 1
+seta hud_panel_score "1"
seta hud_panel_score_pos "0.465000 0.045000"
seta hud_panel_score_size "0.090000 0.060000"
seta hud_panel_score_bg ""
seta hud_panel_score_bg_padding ""
seta hud_panel_score_rankings "1"
-seta hud_panel_racetimer 1
+seta hud_panel_racetimer "1"
seta hud_panel_racetimer_pos "0.360000 0.090000"
seta hud_panel_racetimer_size "0.280000 0.090000"
seta hud_panel_racetimer_bg "0"
seta hud_panel_racetimer_bg_border ""
seta hud_panel_racetimer_bg_padding ""
-seta hud_panel_vote 1
+seta hud_panel_vote "1"
seta hud_panel_vote_pos "0 0.890000"
seta hud_panel_vote_size "0.170000 0.110000"
seta hud_panel_vote_bg ""
seta hud_panel_vote_bg_padding ""
seta hud_panel_vote_alreadyvoted_alpha "0.800000"
-seta hud_panel_modicons 1
+seta hud_panel_modicons "1"
seta hud_panel_modicons_pos "0.560000 0"
seta hud_panel_modicons_size "0.050000 0.100000"
seta hud_panel_modicons_bg ""
seta hud_panel_modicons_dom_layout "1"
seta hud_panel_modicons_freezetag_layout "1"
-seta hud_panel_pressedkeys 1
+seta hud_panel_pressedkeys "1"
seta hud_panel_pressedkeys_pos "0.450000 0.690000"
seta hud_panel_pressedkeys_size "0.100000 0.110000"
seta hud_panel_pressedkeys_bg "0"
seta hud_panel_pressedkeys_aspect "1.600000"
seta hud_panel_pressedkeys_attack "0"
-seta hud_panel_chat 1
+seta hud_panel_chat "1"
seta hud_panel_chat_pos "0 0.775000"
seta hud_panel_chat_size "0.460000 0.110000"
seta hud_panel_chat_bg "0"
seta hud_panel_chat_bg_border ""
seta hud_panel_chat_bg_padding ""
-seta hud_panel_engineinfo 0
+seta hud_panel_engineinfo "0"
seta hud_panel_engineinfo_pos "0.910000 0.970000"
seta hud_panel_engineinfo_size "0.090000 0.030000"
seta hud_panel_engineinfo_bg "0"
seta hud_panel_engineinfo_framecounter_time "0.1"
seta hud_panel_engineinfo_framecounter_decimals "0"
-seta hud_panel_infomessages 1
+seta hud_panel_infomessages "1"
seta hud_panel_infomessages_pos "0.710000 0"
seta hud_panel_infomessages_size "0.290000 0.100000"
seta hud_panel_infomessages_bg "0"
seta hud_panel_infomessages_bg_padding "0"
seta hud_panel_infomessages_flip "1"
-seta hud_panel_physics 3
+seta hud_panel_physics "3"
seta hud_panel_physics_pos "0.270000 0.730000"
seta hud_panel_physics_size "0.170000 0.030000"
seta hud_panel_physics_bg ""
seta hud_panel_physics_bg_alpha ""
seta hud_panel_physics_bg_border ""
seta hud_panel_physics_bg_padding ""
-seta hud_panel_physics_speed_unit "3"
seta hud_panel_physics_speed_unit_show "1"
seta hud_panel_physics_speed_max "1800"
seta hud_panel_physics_speed_vertical "0"
seta hud_panel_physics_text "1"
seta hud_panel_physics_text_scale "0.7"
-seta hud_panel_centerprint 1
+seta hud_panel_centerprint "1"
seta hud_panel_centerprint_pos "0.175000 0.220000"
seta hud_panel_centerprint_size "0.650000 0.220000"
seta hud_panel_centerprint_bg "0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
-seta hud_panel_mapvote 1
-seta hud_panel_mapvote_pos "0 0"
-seta hud_panel_mapvote_size "1 1"
-seta hud_panel_mapvote_bg "0"
-seta hud_panel_mapvote_bg_color ""
-seta hud_panel_mapvote_bg_color_team ""
-seta hud_panel_mapvote_bg_alpha ""
-seta hud_panel_mapvote_bg_border ""
-seta hud_panel_mapvote_bg_padding ""
-
-seta hud_panel_itemstime 2
-seta hud_panel_itemstime_pos "0.000000 0.310000"
-seta hud_panel_itemstime_size "0.070000 0.180000"
-seta hud_panel_itemstime_bg ""
-seta hud_panel_itemstime_bg_color ""
-seta hud_panel_itemstime_bg_color_team ""
-seta hud_panel_itemstime_bg_alpha ""
-seta hud_panel_itemstime_bg_border ""
-seta hud_panel_itemstime_bg_padding ""
-seta hud_panel_itemstime_iconalign "0"
-seta hud_panel_itemstime_progressbar "0"
-seta hud_panel_itemstime_progressbar_name "progressbar"
-seta hud_panel_itemstime_progressbar_reduced "0"
-seta hud_panel_itemstime_text "1"
-seta hud_panel_itemstime_ratio "2"
-seta hud_panel_itemstime_dynamicsize "1"
-
seta hud_panel_minigameboard "1"
seta hud_panel_minigameboard_pos "0.22 0.15"
seta hud_panel_minigameboard_size "0.50 0.60"
seta hud_panel_minigamemenu_bg_border ""
seta hud_panel_minigamemenu_bg_padding ""
-seta hud_panel_quickmenu 1
+seta hud_panel_mapvote "1"
+seta hud_panel_mapvote_pos "0 0"
+seta hud_panel_mapvote_size "1 1"
+seta hud_panel_mapvote_bg "0"
+seta hud_panel_mapvote_bg_color ""
+seta hud_panel_mapvote_bg_color_team ""
+seta hud_panel_mapvote_bg_alpha ""
+seta hud_panel_mapvote_bg_border ""
+seta hud_panel_mapvote_bg_padding ""
+
+seta hud_panel_itemstime "2"
+seta hud_panel_itemstime_pos "0.000000 0.310000"
+seta hud_panel_itemstime_size "0.070000 0.180000"
+seta hud_panel_itemstime_bg ""
+seta hud_panel_itemstime_bg_color ""
+seta hud_panel_itemstime_bg_color_team ""
+seta hud_panel_itemstime_bg_alpha ""
+seta hud_panel_itemstime_bg_border ""
+seta hud_panel_itemstime_bg_padding ""
+seta hud_panel_itemstime_iconalign "0"
+seta hud_panel_itemstime_progressbar "0"
+seta hud_panel_itemstime_progressbar_name "progressbar"
+seta hud_panel_itemstime_progressbar_reduced "0"
+seta hud_panel_itemstime_text "1"
+seta hud_panel_itemstime_ratio "2"
+seta hud_panel_itemstime_dynamicsize "1"
+
+seta hud_panel_quickmenu "1"
seta hud_panel_quickmenu_pos "0.600000 0.460000"
seta hud_panel_quickmenu_size "0.190000 0.190000"
seta hud_panel_quickmenu_bg ""
seta hud_configure_grid_xsize "0.010000"
seta hud_configure_grid_ysize "0.010000"
-seta hud_panel_weapons 1
+seta hud_panel_weapons "1"
seta hud_panel_weapons_pos "0.920000 0.090000"
seta hud_panel_weapons_size "0.060000 0.630000"
seta hud_panel_weapons_bg ""
seta hud_panel_weapons_noncurrent_alpha "1"
seta hud_panel_weapons_noncurrent_scale "1"
-seta hud_panel_ammo 1
+seta hud_panel_ammo "1"
seta hud_panel_ammo_pos "0.190000 0.920000"
seta hud_panel_ammo_size "0.120000 0.070000"
seta hud_panel_ammo_bg ""
seta hud_panel_ammo_progressbar_xoffset "0"
seta hud_panel_ammo_text "1"
-seta hud_panel_powerups 1
+seta hud_panel_powerups "1"
seta hud_panel_powerups_pos "0.660000 0.940000"
seta hud_panel_powerups_size "0.330000 0.060000"
seta hud_panel_powerups_bg "0"
seta hud_panel_powerups_progressbar "1"
seta hud_panel_powerups_text "1"
-seta hud_panel_healtharmor 1
+seta hud_panel_healtharmor "1"
seta hud_panel_healtharmor_pos "0.330000 0.920000"
seta hud_panel_healtharmor_size "0.310000 0.070000"
seta hud_panel_healtharmor_bg ""
seta hud_panel_healtharmor_progressbar_gfx_smooth "2"
seta hud_panel_healtharmor_text "1"
-seta hud_panel_notify 1
+seta hud_panel_notify "1"
seta hud_panel_notify_pos "0.660000 0.730000"
seta hud_panel_notify_size "0.320000 0.190000"
seta hud_panel_notify_bg "0"
seta hud_panel_notify_fadetime "3"
seta hud_panel_notify_icon_aspect "2"
-seta hud_panel_timer 1
+seta hud_panel_timer "1"
seta hud_panel_timer_pos "0.870000 0"
seta hud_panel_timer_size "0.130000 0.060000"
seta hud_panel_timer_bg "0"
seta hud_panel_timer_bg_alpha ""
seta hud_panel_timer_bg_border ""
seta hud_panel_timer_bg_padding "0"
-seta hud_panel_timer_increment "0"
-seta hud_panel_radar 2
+seta hud_panel_radar "2"
seta hud_panel_radar_pos "0.030000 0.020000"
seta hud_panel_radar_size "0.170000 0.220000"
seta hud_panel_radar_bg ""
seta hud_panel_radar_maximized_rotation "1"
seta hud_panel_radar_maximized_zoommode "3"
-seta hud_panel_score 1
+seta hud_panel_score "1"
seta hud_panel_score_pos "0.020000 0.920000"
seta hud_panel_score_size "0.150000 0.070000"
seta hud_panel_score_bg ""
seta hud_panel_score_bg_padding ""
seta hud_panel_score_rankings "1"
-seta hud_panel_racetimer 1
+seta hud_panel_racetimer "1"
seta hud_panel_racetimer_pos "0.360000 0.090000"
seta hud_panel_racetimer_size "0.280000 0.090000"
seta hud_panel_racetimer_bg "0"
seta hud_panel_racetimer_bg_border ""
seta hud_panel_racetimer_bg_padding ""
-seta hud_panel_vote 1
+seta hud_panel_vote "1"
seta hud_panel_vote_pos "0.020000 0.650000"
seta hud_panel_vote_size "0.230000 0.110000"
seta hud_panel_vote_bg ""
seta hud_panel_vote_bg_padding ""
seta hud_panel_vote_alreadyvoted_alpha "0.800000"
-seta hud_panel_modicons 1
+seta hud_panel_modicons "1"
seta hud_panel_modicons_pos "0.040000 0.270000"
seta hud_panel_modicons_size "0.080000 0.200000"
seta hud_panel_modicons_bg ""
seta hud_panel_modicons_dom_layout "1"
seta hud_panel_modicons_freezetag_layout "1"
-seta hud_panel_pressedkeys 1
+seta hud_panel_pressedkeys "1"
seta hud_panel_pressedkeys_pos "0.410000 0.710000"
seta hud_panel_pressedkeys_size "0.180000 0.130000"
seta hud_panel_pressedkeys_bg "0"
seta hud_panel_pressedkeys_aspect "1.600000"
seta hud_panel_pressedkeys_attack "0"
-seta hud_panel_chat 1
+seta hud_panel_chat "1"
seta hud_panel_chat_pos "0.020000 0.780000"
seta hud_panel_chat_size "0.630000 0.110000"
seta hud_panel_chat_bg "0"
seta hud_panel_chat_bg_border ""
seta hud_panel_chat_bg_padding ""
-seta hud_panel_engineinfo 0
+seta hud_panel_engineinfo "0"
seta hud_panel_engineinfo_pos "0.910000 0.970000"
seta hud_panel_engineinfo_size "0.090000 0.030000"
seta hud_panel_engineinfo_bg "0"
seta hud_panel_engineinfo_framecounter_time "0.1"
seta hud_panel_engineinfo_framecounter_decimals "0"
-seta hud_panel_infomessages 1
+seta hud_panel_infomessages "1"
seta hud_panel_infomessages_pos "0.510000 0"
seta hud_panel_infomessages_size "0.340000 0.090000"
seta hud_panel_infomessages_bg "0"
seta hud_panel_infomessages_bg_padding "0"
seta hud_panel_infomessages_flip "1"
-seta hud_panel_physics 3
+seta hud_panel_physics "3"
seta hud_panel_physics_pos "0.410000 0.590000"
seta hud_panel_physics_size "0.180000 0.100000"
seta hud_panel_physics_bg ""
seta hud_panel_physics_bg_alpha ""
seta hud_panel_physics_bg_border ""
seta hud_panel_physics_bg_padding ""
-seta hud_panel_physics_speed_unit "3"
seta hud_panel_physics_speed_unit_show "1"
seta hud_panel_physics_speed_max "1800"
seta hud_panel_physics_speed_vertical "0"
seta hud_panel_physics_text "1"
seta hud_panel_physics_text_scale "0.7"
-seta hud_panel_centerprint 1
+seta hud_panel_centerprint "1"
seta hud_panel_centerprint_pos "0.175000 0.220000"
seta hud_panel_centerprint_size "0.650000 0.220000"
seta hud_panel_centerprint_bg "0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
-seta hud_panel_mapvote 1
-seta hud_panel_mapvote_pos "0 0"
-seta hud_panel_mapvote_size "1 1"
-seta hud_panel_mapvote_bg "0"
-seta hud_panel_mapvote_bg_color ""
-seta hud_panel_mapvote_bg_color_team ""
-seta hud_panel_mapvote_bg_alpha ""
-seta hud_panel_mapvote_bg_border ""
-seta hud_panel_mapvote_bg_padding ""
-
-seta hud_panel_itemstime 2
-seta hud_panel_itemstime_pos "0.020000 0.490000"
-seta hud_panel_itemstime_size "0.090000 0.140000"
-seta hud_panel_itemstime_bg "0"
-seta hud_panel_itemstime_bg_color ""
-seta hud_panel_itemstime_bg_color_team ""
-seta hud_panel_itemstime_bg_alpha ""
-seta hud_panel_itemstime_bg_border ""
-seta hud_panel_itemstime_bg_padding ""
-seta hud_panel_itemstime_iconalign "0"
-seta hud_panel_itemstime_progressbar "1"
-seta hud_panel_itemstime_progressbar_name "progressbar"
-seta hud_panel_itemstime_progressbar_reduced "1"
-seta hud_panel_itemstime_text "1"
-seta hud_panel_itemstime_ratio "3.5"
-seta hud_panel_itemstime_dynamicsize "1"
-
seta hud_panel_minigameboard "1"
seta hud_panel_minigameboard_pos "0.22 0.15"
seta hud_panel_minigameboard_size "0.50 0.60"
seta hud_panel_minigamemenu_bg_border ""
seta hud_panel_minigamemenu_bg_padding ""
-seta hud_panel_quickmenu 1
+seta hud_panel_mapvote "1"
+seta hud_panel_mapvote_pos "0 0"
+seta hud_panel_mapvote_size "1 1"
+seta hud_panel_mapvote_bg "0"
+seta hud_panel_mapvote_bg_color ""
+seta hud_panel_mapvote_bg_color_team ""
+seta hud_panel_mapvote_bg_alpha ""
+seta hud_panel_mapvote_bg_border ""
+seta hud_panel_mapvote_bg_padding ""
+
+seta hud_panel_itemstime "2"
+seta hud_panel_itemstime_pos "0.020000 0.490000"
+seta hud_panel_itemstime_size "0.090000 0.140000"
+seta hud_panel_itemstime_bg "0"
+seta hud_panel_itemstime_bg_color ""
+seta hud_panel_itemstime_bg_color_team ""
+seta hud_panel_itemstime_bg_alpha ""
+seta hud_panel_itemstime_bg_border ""
+seta hud_panel_itemstime_bg_padding ""
+seta hud_panel_itemstime_iconalign "0"
+seta hud_panel_itemstime_progressbar "1"
+seta hud_panel_itemstime_progressbar_name "progressbar"
+seta hud_panel_itemstime_progressbar_reduced "1"
+seta hud_panel_itemstime_text "1"
+seta hud_panel_itemstime_ratio "3.500000"
+seta hud_panel_itemstime_dynamicsize "1"
+
+seta hud_panel_quickmenu "1"
seta hud_panel_quickmenu_pos "0.700000 0.460000"
seta hud_panel_quickmenu_size "0.210000 0.250000"
seta hud_panel_quickmenu_bg ""
seta _hud_panelorder "17 15 0 11 8 5 6 14 9 13 7 2 3 1 10 12 4 16 18 23 19 20 21 22 "
seta hud_configure_grid "1"
-seta hud_configure_grid_xsize "0.01"
-seta hud_configure_grid_ysize "0.01"
+seta hud_configure_grid_xsize "0.010000"
+seta hud_configure_grid_ysize "0.010000"
-seta hud_panel_weapons 1
+seta hud_panel_weapons "1"
seta hud_panel_weapons_pos "0.375000 0.870000"
seta hud_panel_weapons_size "0.300000 0.060000"
seta hud_panel_weapons_bg "0"
seta hud_panel_weapons_noncurrent_alpha "1"
seta hud_panel_weapons_noncurrent_scale "1"
-seta hud_panel_ammo 1
+seta hud_panel_ammo "1"
seta hud_panel_ammo_pos "0.160000 0.910000"
seta hud_panel_ammo_size "0.190000 0.090000"
seta hud_panel_ammo_bg "0"
seta hud_panel_ammo_progressbar_xoffset "0"
seta hud_panel_ammo_text "1"
-seta hud_panel_powerups 1
+seta hud_panel_powerups "1"
seta hud_panel_powerups_pos "0.660000 0.910000"
seta hud_panel_powerups_size "0.130000 0.090000"
seta hud_panel_powerups_bg "0"
seta hud_panel_powerups_progressbar "0"
seta hud_panel_powerups_text "1"
-seta hud_panel_healtharmor 1
+seta hud_panel_healtharmor "1"
seta hud_panel_healtharmor_pos "0.370000 0.930000"
seta hud_panel_healtharmor_size "0.300000 0.070000"
seta hud_panel_healtharmor_bg "0"
seta hud_panel_healtharmor_progressbar_gfx_smooth "2"
seta hud_panel_healtharmor_text "1"
-seta hud_panel_notify 0
+seta hud_panel_notify "0"
seta hud_panel_notify_pos "0.010000 0.650000"
seta hud_panel_notify_size "0.300000 0.070000"
seta hud_panel_notify_bg "0"
seta hud_panel_notify_fadetime "3"
seta hud_panel_notify_icon_aspect "2"
-seta hud_panel_timer 1
+seta hud_panel_timer "1"
seta hud_panel_timer_pos "0.850000 0"
seta hud_panel_timer_size "0.150000 0.060000"
seta hud_panel_timer_bg ""
seta hud_panel_timer_bg_alpha ""
seta hud_panel_timer_bg_border ""
seta hud_panel_timer_bg_padding "0"
-seta hud_panel_timer_increment "0"
-seta hud_panel_radar 2
+seta hud_panel_radar "2"
seta hud_panel_radar_pos "0 0"
seta hud_panel_radar_size "0.200000 0.260000"
seta hud_panel_radar_bg "border_radar"
seta hud_panel_radar_maximized_rotation "1"
seta hud_panel_radar_maximized_zoommode "3"
-seta hud_panel_score 1
+seta hud_panel_score "1"
seta hud_panel_score_pos "0.760000 0.910000"
seta hud_panel_score_size "0.200000 0.080000"
seta hud_panel_score_bg "0"
seta hud_panel_score_bg_padding ""
seta hud_panel_score_rankings "0"
-seta hud_panel_racetimer 1
+seta hud_panel_racetimer "1"
seta hud_panel_racetimer_pos "0.360000 0.140000"
seta hud_panel_racetimer_size "0.280000 0.090000"
seta hud_panel_racetimer_bg "0"
seta hud_panel_racetimer_bg_border ""
seta hud_panel_racetimer_bg_padding ""
-seta hud_panel_vote 1
+seta hud_panel_vote "1"
seta hud_panel_vote_pos "0.690000 0.750000"
seta hud_panel_vote_size "0.300000 0.100000"
seta hud_panel_vote_bg ""
seta hud_panel_vote_bg_padding "-3"
seta hud_panel_vote_alreadyvoted_alpha "0.750000"
-seta hud_panel_modicons 1
+seta hud_panel_modicons "1"
seta hud_panel_modicons_pos "0.010000 0.910000"
seta hud_panel_modicons_size "0.135000 0.090000"
seta hud_panel_modicons_bg "0"
seta hud_panel_modicons_dom_layout "1"
seta hud_panel_modicons_freezetag_layout "1"
-seta hud_panel_pressedkeys 1
+seta hud_panel_pressedkeys "1"
seta hud_panel_pressedkeys_pos "0.440000 0.760000"
seta hud_panel_pressedkeys_size "0.120000 0.094368"
seta hud_panel_pressedkeys_bg "0"
seta hud_panel_pressedkeys_aspect "1.600000"
seta hud_panel_pressedkeys_attack "0"
-seta hud_panel_chat 1
+seta hud_panel_chat "1"
seta hud_panel_chat_pos "0 0.760000"
seta hud_panel_chat_size "0.420000 0.130000"
seta hud_panel_chat_bg "0"
seta hud_panel_chat_bg_border ""
seta hud_panel_chat_bg_padding ""
-seta hud_panel_engineinfo 0
+seta hud_panel_engineinfo "0"
seta hud_panel_engineinfo_pos "0.887500 0.870000"
seta hud_panel_engineinfo_size "0.112500 0.030000"
seta hud_panel_engineinfo_bg "0"
seta hud_panel_engineinfo_framecounter_time "0.1"
seta hud_panel_engineinfo_framecounter_decimals "0"
-seta hud_panel_infomessages 1
+seta hud_panel_infomessages "1"
seta hud_panel_infomessages_pos "0.690000 0.620000"
seta hud_panel_infomessages_size "0.300000 0.100000"
seta hud_panel_infomessages_bg "0"
seta hud_panel_infomessages_bg_padding ""
seta hud_panel_infomessages_flip "1"
-seta hud_panel_physics 3
+seta hud_panel_physics "3"
seta hud_panel_physics_pos "0.430000 0.640000"
seta hud_panel_physics_size "0.140000 0.100000"
seta hud_panel_physics_bg "0"
seta hud_panel_physics_bg_alpha ""
seta hud_panel_physics_bg_border ""
seta hud_panel_physics_bg_padding ""
-seta hud_panel_physics_speed_unit "1"
seta hud_panel_physics_speed_unit_show "0"
seta hud_panel_physics_speed_max "1800"
seta hud_panel_physics_speed_vertical "0"
seta hud_panel_physics_text "2"
seta hud_panel_physics_text_scale "1"
-seta hud_panel_centerprint 1
+seta hud_panel_centerprint "1"
seta hud_panel_centerprint_pos "0.175000 0.260000"
seta hud_panel_centerprint_size "0.650000 0.200000"
seta hud_panel_centerprint_bg "0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
-seta hud_panel_mapvote 1
-seta hud_panel_mapvote_pos "0 0"
-seta hud_panel_mapvote_size "1 1"
-seta hud_panel_mapvote_bg "0"
-seta hud_panel_mapvote_bg_color ""
-seta hud_panel_mapvote_bg_color_team ""
-seta hud_panel_mapvote_bg_alpha ""
-seta hud_panel_mapvote_bg_border ""
-seta hud_panel_mapvote_bg_padding ""
-
-seta hud_panel_itemstime 2
-seta hud_panel_itemstime_pos "0.000000 0.290000"
-seta hud_panel_itemstime_size "0.150000 0.060000"
-seta hud_panel_itemstime_bg "0"
-seta hud_panel_itemstime_bg_color ""
-seta hud_panel_itemstime_bg_color_team ""
-seta hud_panel_itemstime_bg_alpha ""
-seta hud_panel_itemstime_bg_border ""
-seta hud_panel_itemstime_bg_padding ""
-seta hud_panel_itemstime_iconalign "0"
-seta hud_panel_itemstime_progressbar "0"
-seta hud_panel_itemstime_progressbar_name "progressbar"
-seta hud_panel_itemstime_progressbar_reduced "0"
-seta hud_panel_itemstime_text "1"
-seta hud_panel_itemstime_ratio "2"
-seta hud_panel_itemstime_dynamicsize "1"
-
seta hud_panel_minigameboard "1"
seta hud_panel_minigameboard_pos "0.22 0.15"
seta hud_panel_minigameboard_size "0.50 0.60"
seta hud_panel_minigamemenu_bg_border ""
seta hud_panel_minigamemenu_bg_padding ""
-seta hud_panel_quickmenu 1
+seta hud_panel_mapvote "1"
+seta hud_panel_mapvote_pos "0 0"
+seta hud_panel_mapvote_size "1 1"
+seta hud_panel_mapvote_bg "0"
+seta hud_panel_mapvote_bg_color ""
+seta hud_panel_mapvote_bg_color_team ""
+seta hud_panel_mapvote_bg_alpha ""
+seta hud_panel_mapvote_bg_border ""
+seta hud_panel_mapvote_bg_padding ""
+
+seta hud_panel_itemstime "2"
+seta hud_panel_itemstime_pos "0.000000 0.290000"
+seta hud_panel_itemstime_size "0.150000 0.060000"
+seta hud_panel_itemstime_bg "0"
+seta hud_panel_itemstime_bg_color ""
+seta hud_panel_itemstime_bg_color_team ""
+seta hud_panel_itemstime_bg_alpha ""
+seta hud_panel_itemstime_bg_border ""
+seta hud_panel_itemstime_bg_padding ""
+seta hud_panel_itemstime_iconalign "0"
+seta hud_panel_itemstime_progressbar "0"
+seta hud_panel_itemstime_progressbar_name "progressbar"
+seta hud_panel_itemstime_progressbar_reduced "0"
+seta hud_panel_itemstime_text "1"
+seta hud_panel_itemstime_ratio "2"
+seta hud_panel_itemstime_dynamicsize "1"
+
+seta hud_panel_quickmenu "1"
seta hud_panel_quickmenu_pos "0.010000 0.380000"
seta hud_panel_quickmenu_size "0.210000 0.250000"
seta hud_panel_quickmenu_bg ""
-ast Asturian "Asturianu (60%)"
-de German "Deutsch (90%)"
-de_CH German "Deutsch (Schweiz) (90%)"
-en_AU en_AU "en_AU (77%)"
-en English "English"
-es Spanish "Español (68%)"
-fr French "Français (98%)"
-it Italian "Italiano (97%)"
-hu Hungarian "Magyar (50%)"
-nl Dutch "Nederlands (45%)"
-pl Polish "Polski (60%)"
-pt Portuguese "Português (42%)"
-ro Romanian "Romana (90%)"
-fi Finnish "Suomi (35%)"
-el Greek "Ελληνική (25%)"
-be Belarusian "Беларуская (65%)"
-bg Bulgarian "Български (65%)"
-ru Russian "Русский (93%)"
-uk Ukrainian "Українська (60%)"
+ast Asturian "Asturianu" 60%
+de German "Deutsch" 90%
+de_CH German "Deutsch (Schweiz)" 90%
+en English "English"
+en_AU English "English (Australia)" 77%
+es Spanish "Español" 68%
+fr French "Français" 98%
+it Italian "Italiano" 97%
+hu Hungarian "Magyar" 50%
+nl Dutch "Nederlands" 45%
+pl Polish "Polski" 60%
+pt Portuguese "Português" 42%
+ro Romanian "Romana" 90%
+fi Finnish "Suomi" 35%
+el Greek "Ελληνική" 25%
+be Belarusian "Беларуская" 65%
+bg Bulgarian "Български" 65%
+ru Russian "Русский" 93%
+uk Ukrainian "Українська" 60%
\ No newline at end of file
--- /dev/null
+// bulldozer storage "level1" last updated 16-11-2015 03:11:33
+nextlevel = "level2"
+"k11" 1 "0 -1 0"
+"a20" 6 "0 0 0"
+"a19" 6 "0 0 0"
+"a18" 6 "0 0 0"
+"a17" 6 "0 0 0"
+"a15" 6 "0 0 0"
+"a14" 6 "0 0 0"
+"a13" 6 "0 0 0"
+"a12" 6 "0 0 0"
+"a11" 6 "0 0 0"
+"a10" 6 "0 0 0"
+"a9" 6 "0 0 0"
+"a8" 6 "0 0 0"
+"a7" 6 "0 0 0"
+"a6" 6 "0 0 0"
+"a5" 6 "0 0 0"
+"a4" 6 "0 0 0"
+"a3" 6 "0 0 0"
+"a2" 6 "0 0 0"
+"a1" 6 "0 0 0"
+"b1" 6 "0 0 0"
+"c1" 6 "0 0 0"
+"d1" 6 "0 0 0"
+"e1" 6 "0 0 0"
+"f1" 6 "0 0 0"
+"g1" 6 "0 0 0"
+"h1" 6 "0 0 0"
+"i1" 6 "0 0 0"
+"j1" 6 "0 0 0"
+"k1" 6 "0 0 0"
+"l1" 6 "0 0 0"
+"m1" 6 "0 0 0"
+"n1" 6 "0 0 0"
+"o1" 6 "0 0 0"
+"p1" 6 "0 0 0"
+"q1" 6 "0 0 0"
+"r1" 6 "0 0 0"
+"s1" 6 "0 0 0"
+"t1" 6 "0 0 0"
+"t2" 6 "0 0 0"
+"t3" 6 "0 0 0"
+"t4" 6 "0 0 0"
+"t5" 6 "0 0 0"
+"t6" 6 "0 0 0"
+"t7" 6 "0 0 0"
+"t8" 6 "0 0 0"
+"t9" 6 "0 0 0"
+"t10" 6 "0 0 0"
+"t11" 6 "0 0 0"
+"t12" 6 "0 0 0"
+"t13" 6 "0 0 0"
+"t14" 6 "0 0 0"
+"t15" 6 "0 0 0"
+"t16" 6 "0 0 0"
+"t17" 6 "0 0 0"
+"t18" 6 "0 0 0"
+"t19" 6 "0 0 0"
+"t20" 6 "0 0 0"
+"s20" 6 "0 0 0"
+"r20" 6 "0 0 0"
+"q20" 6 "0 0 0"
+"p20" 6 "0 0 0"
+"o20" 6 "0 0 0"
+"n20" 6 "0 0 0"
+"m20" 6 "0 0 0"
+"l20" 6 "0 0 0"
+"k20" 6 "0 0 0"
+"j20" 6 "0 0 0"
+"i20" 6 "0 0 0"
+"h20" 6 "0 0 0"
+"g20" 6 "0 0 0"
+"f20" 6 "0 0 0"
+"e20" 6 "0 0 0"
+"d20" 6 "0 0 0"
+"c20" 6 "0 0 0"
+"b20" 6 "0 0 0"
+"a16" 6 "0 0 0"
+"b2" 4 "0 0 0"
+"c18" 6 "0 0 0"
+"e18" 6 "0 0 0"
+"e17" 6 "0 0 0"
+"e16" 6 "0 0 0"
+"e15" 6 "0 0 0"
+"e14" 6 "0 0 0"
+"e13" 6 "0 0 0"
+"e12" 6 "0 0 0"
+"e11" 6 "0 0 0"
+"f10" 4 "0 0 0"
+"e9" 6 "0 0 0"
+"e8" 6 "0 0 0"
+"e7" 6 "0 0 0"
+"e6" 6 "0 0 0"
+"e5" 6 "0 0 0"
+"e4" 6 "0 0 0"
+"e3" 6 "0 0 0"
+"e2" 6 "0 0 0"
+"e19" 6 "0 0 0"
+"c17" 6 "0 0 0"
+"c16" 6 "0 0 0"
+"c15" 6 "0 0 0"
+"c14" 6 "0 0 0"
+"c13" 6 "0 0 0"
+"c12" 6 "0 0 0"
+"c11" 6 "0 0 0"
+"c10" 6 "0 0 0"
+"c9" 6 "0 0 0"
+"c8" 6 "0 0 0"
+"c7" 6 "0 0 0"
+"c6" 6 "0 0 0"
+"c5" 6 "0 0 0"
+"c4" 6 "0 0 0"
+"c3" 6 "0 0 0"
+"c2" 6 "0 0 0"
+"c19" 6 "0 0 0"
+"i14" 5 "0 0 0"
+"f12" 4 "0 0 0"
+"f11" 4 "0 0 0"
+"e10" 6 "0 0 0"
+"i10" 5 "0 0 0"
+"h10" 5 "0 0 0"
+"j10" 5 "0 0 0"
+"j9" 5 "0 0 0"
+"g11" 5 "0 0 0"
+"j8" 5 "0 0 0"
+"k8" 5 "0 0 0"
+"l8" 5 "0 0 0"
+"l9" 5 "0 0 0"
+"i8" 4 "0 0 0"
+"i9" 4 "0 0 0"
+"m11" 5 "0 0 0"
+"l10" 5 "0 0 0"
+"n11" 5 "0 0 0"
+"n13" 5 "0 0 0"
+"n12" 5 "0 0 0"
+"m13" 5 "0 0 0"
+"k13" 5 "0 0 0"
+"k14" 5 "0 0 0"
+"k15" 5 "0 0 0"
+"j15" 5 "0 0 0"
+"i13" 5 "0 0 0"
+"h15" 4 "0 0 0"
+"h14" 4 "0 0 0"
+"h13" 4 "0 0 0"
+"g15" 4 "0 0 0"
+"p17" 6 "0 0 0"
+"p16" 6 "0 0 0"
+"l13" 5 "0 0 0"
+"h12" 5 "0 0 0"
+"i15" 5 "0 0 0"
+"l15" 4 "0 0 0"
+"m15" 4 "0 0 0"
+"l14" 4 "0 0 0"
+"m14" 4 "0 0 0"
+"n14" 4 "0 0 0"
+"p15" 6 "0 0 0"
+"p14" 6 "0 0 0"
+"l11" 5 "0 0 0"
+"h11" 2 "0 0 0"
+"k9" 2 "0 0 0"
+"j14" 2 "0 0 0"
+"m12" 2 "0 0 0"
+"l12" 3 "0 0 0"
+"j11" 3 "0 0 0"
+"j12" 3 "0 0 0"
+"k10" 3 "0 0 0"
+"i12" 5 "0 0 0"
+"g12" 5 "0 0 0"
+"g10" 5 "0 0 0"
+"p13" 6 "0 0 0"
+"p12" 6 "0 0 0"
+"p11" 6 "0 0 0"
+"p10" 6 "0 0 0"
+"p9" 6 "0 0 0"
+"p8" 6 "0 0 0"
+"p7" 6 "0 0 0"
+"p6" 6 "0 0 0"
+"p5" 6 "0 0 0"
+"p4" 6 "0 0 0"
+"p3" 6 "0 0 0"
+"p2" 6 "0 0 0"
+"p18" 6 "0 0 0"
+"p19" 6 "0 0 0"
+"r16" 6 "0 0 0"
+"r15" 6 "0 0 0"
+"r14" 6 "0 0 0"
+"r13" 6 "0 0 0"
+"r12" 6 "0 0 0"
+"r11" 6 "0 0 0"
+"r10" 6 "0 0 0"
+"r9" 6 "0 0 0"
+"r8" 6 "0 0 0"
+"r7" 6 "0 0 0"
+"r6" 6 "0 0 0"
+"r5" 6 "0 0 0"
+"r4" 6 "0 0 0"
+"r3" 6 "0 0 0"
+"r2" 6 "0 0 0"
+"r17" 6 "0 0 0"
+"r18" 6 "0 0 0"
+"r19" 6 "0 0 0"
+"d12" 4 "0 0 0"
+"d6" 4 "0 0 0"
+"f6" 4 "0 0 0"
+"f7" 4 "0 0 0"
+"f8" 4 "0 0 0"
+"f9" 4 "0 0 0"
+"h9" 4 "0 0 0"
+"g9" 4 "0 0 0"
+"g8" 4 "0 0 0"
+"g7" 4 "0 0 0"
+"g6" 4 "0 0 0"
+"g5" 4 "0 0 0"
+"g4" 4 "0 0 0"
+"h6" 4 "0 0 0"
+"h7" 4 "0 0 0"
+"h8" 4 "0 0 0"
+"i7" 4 "0 0 0"
+"i6" 4 "0 0 0"
+"j6" 4 "0 0 0"
+"k6" 4 "0 0 0"
+"j7" 4 "0 0 0"
+"k7" 4 "0 0 0"
+"l6" 4 "0 0 0"
+"l7" 4 "0 0 0"
+"m10" 4 "0 0 0"
+"m8" 4 "0 0 0"
+"m7" 4 "0 0 0"
+"m6" 4 "0 0 0"
+"m5" 4 "0 0 0"
+"m4" 4 "0 0 0"
+"m3" 4 "0 0 0"
+"m2" 4 "0 0 0"
+"f19" 4 "0 0 0"
+"f18" 4 "0 0 0"
+"f17" 4 "0 0 0"
+"f16" 4 "0 0 0"
+"f15" 4 "0 0 0"
+"f13" 4 "0 0 0"
+"l3" 4 "0 0 0"
+"l4" 4 "0 0 0"
+"l5" 4 "0 0 0"
+"j3" 4 "0 0 0"
+"j2" 4 "0 0 0"
+"k3" 4 "0 0 0"
+"i3" 4 "0 0 0"
+"g3" 4 "0 0 0"
+"h3" 4 "0 0 0"
+"f3" 4 "0 0 0"
+"d3" 4 "0 0 0"
+"d19" 4 "0 0 0"
+"d17" 4 "0 0 0"
+"d5" 4 "0 0 0"
+"d4" 4 "0 0 0"
+"d7" 4 "0 0 0"
+"h5" 4 "0 0 0"
+"h4" 4 "0 0 0"
+"i4" 4 "0 0 0"
+"j4" 4 "0 0 0"
+"k5" 4 "0 0 0"
+"j5" 4 "0 0 0"
+"i5" 4 "0 0 0"
+"d18" 4 "0 0 0"
+"d10" 4 "0 0 0"
+"g13" 4 "0 0 0"
+"g14" 4 "0 0 0"
+"k4" 4 "0 0 0"
+"d8" 4 "0 0 0"
+"d9" 4 "0 0 0"
+"g16" 4 "0 0 0"
+"g17" 4 "0 0 0"
+"g18" 4 "0 0 0"
+"d11" 4 "0 0 0"
+"g19" 4 "0 0 0"
+"h19" 4 "0 0 0"
+"h18" 4 "0 0 0"
+"h16" 4 "0 0 0"
+"h17" 4 "0 0 0"
+"i16" 4 "0 0 0"
+"i17" 4 "0 0 0"
+"i18" 4 "0 0 0"
+"j19" 4 "0 0 0"
+"j18" 4 "0 0 0"
+"j17" 4 "0 0 0"
+"i19" 4 "0 0 0"
+"j16" 4 "0 0 0"
+"k16" 4 "0 0 0"
+"k17" 4 "0 0 0"
+"k18" 4 "0 0 0"
+"k19" 4 "0 0 0"
+"l19" 4 "0 0 0"
+"f5" 4 "0 0 0"
+"f4" 4 "0 0 0"
+"l18" 4 "0 0 0"
+"l17" 4 "0 0 0"
+"l16" 4 "0 0 0"
+"m16" 4 "0 0 0"
+"m17" 4 "0 0 0"
+"m18" 4 "0 0 0"
+"n19" 4 "0 0 0"
+"m19" 4 "0 0 0"
+"n18" 4 "0 0 0"
+"n17" 4 "0 0 0"
+"n16" 4 "0 0 0"
+"n15" 4 "0 0 0"
+"n10" 4 "0 0 0"
+"n9" 4 "0 0 0"
+"n8" 4 "0 0 0"
+"n7" 4 "0 0 0"
+"n6" 4 "0 0 0"
+"n5" 4 "0 0 0"
+"n4" 4 "0 0 0"
+"n3" 4 "0 0 0"
+"m9" 4 "0 0 0"
+"s2" 4 "0 0 0"
+"s3" 4 "0 0 0"
+"s4" 4 "0 0 0"
+"s5" 4 "0 0 0"
+"s6" 4 "0 0 0"
+"s7" 4 "0 0 0"
+"s8" 4 "0 0 0"
+"s9" 4 "0 0 0"
+"s10" 4 "0 0 0"
+"s11" 4 "0 0 0"
+"s12" 4 "0 0 0"
+"s13" 4 "0 0 0"
+"s14" 4 "0 0 0"
+"s15" 4 "0 0 0"
+"s16" 4 "0 0 0"
+"s17" 4 "0 0 0"
+"s18" 4 "0 0 0"
+"s19" 4 "0 0 0"
+"q19" 4 "0 0 0"
+"o19" 4 "0 0 0"
+"o18" 4 "0 0 0"
+"o17" 4 "0 0 0"
+"o16" 4 "0 0 0"
+"o15" 4 "0 0 0"
+"o14" 4 "0 0 0"
+"o13" 4 "0 0 0"
+"o12" 4 "0 0 0"
+"o11" 4 "0 0 0"
+"o10" 4 "0 0 0"
+"o9" 4 "0 0 0"
+"o8" 4 "0 0 0"
+"o7" 4 "0 0 0"
+"o6" 4 "0 0 0"
+"o5" 4 "0 0 0"
+"o4" 4 "0 0 0"
+"o3" 4 "0 0 0"
+"q8" 4 "0 0 0"
+"q15" 4 "0 0 0"
+"q16" 4 "0 0 0"
+"q17" 4 "0 0 0"
+"q18" 4 "0 0 0"
+"q3" 4 "0 0 0"
+"q4" 4 "0 0 0"
+"q6" 4 "0 0 0"
+"q7" 4 "0 0 0"
+"q5" 4 "0 0 0"
+"q9" 4 "0 0 0"
+"q10" 4 "0 0 0"
+"q11" 4 "0 0 0"
+"q12" 4 "0 0 0"
+"q13" 4 "0 0 0"
+"q14" 4 "0 0 0"
+"b14" 4 "0 0 0"
+"b13" 4 "0 0 0"
+"d13" 4 "0 0 0"
+"d14" 4 "0 0 0"
+"d15" 4 "0 0 0"
+"b15" 4 "0 0 0"
+"b16" 4 "0 0 0"
+"d16" 4 "0 0 0"
+"b17" 4 "0 0 0"
+"b18" 4 "0 0 0"
+"b19" 4 "0 0 0"
+"f2" 4 "0 0 0"
+"g2" 4 "0 0 0"
+"h2" 4 "0 0 0"
+"i2" 4 "0 0 0"
+"k2" 4 "0 0 0"
+"l2" 4 "0 0 0"
+"n2" 4 "0 0 0"
+"o2" 4 "0 0 0"
+"q2" 4 "0 0 0"
+"f14" 4 "0 0 0"
+"b12" 4 "0 0 0"
+"b11" 4 "0 0 0"
+"b10" 4 "0 0 0"
+"b9" 4 "0 0 0"
+"b8" 4 "0 0 0"
+"b7" 4 "0 0 0"
+"b6" 4 "0 0 0"
+"b5" 4 "0 0 0"
+"b4" 4 "0 0 0"
+"b3" 4 "0 0 0"
+"d2" 4 "0 0 0"
--- /dev/null
+// bulldozer storage "level2" last updated 16-11-2015 03:34:13
+nextlevel = "level3"
+"a20" 4 "0 0 0"
+"b20" 4 "0 0 0"
+"c20" 4 "0 0 0"
+"d20" 4 "0 0 0"
+"e20" 4 "0 0 0"
+"r13" 5 "0 0 0"
+"f20" 4 "0 0 0"
+"g20" 4 "0 0 0"
+"c12" 5 "0 0 0"
+"h20" 4 "0 0 0"
+"c13" 5 "0 0 0"
+"i20" 4 "0 0 0"
+"c14" 5 "0 0 0"
+"j20" 4 "0 0 0"
+"c15" 5 "0 0 0"
+"k20" 4 "0 0 0"
+"c16" 5 "0 0 0"
+"l20" 4 "0 0 0"
+"c17" 5 "0 0 0"
+"m20" 4 "0 0 0"
+"c18" 5 "0 0 0"
+"n20" 4 "0 0 0"
+"c19" 5 "0 0 0"
+"o20" 4 "0 0 0"
+"r18" 5 "0 0 0"
+"p20" 4 "0 0 0"
+"r17" 5 "0 0 0"
+"q20" 4 "0 0 0"
+"r12" 5 "0 0 0"
+"r20" 4 "0 0 0"
+"r15" 5 "0 0 0"
+"r14" 5 "0 0 0"
+"s20" 4 "0 0 0"
+"t20" 4 "0 0 0"
+"t19" 4 "0 0 0"
+"t18" 4 "0 0 0"
+"t17" 4 "0 0 0"
+"t16" 4 "0 0 0"
+"t15" 4 "0 0 0"
+"t14" 4 "0 0 0"
+"t13" 4 "0 0 0"
+"t9" 4 "0 0 0"
+"s9" 4 "0 0 0"
+"r9" 4 "0 0 0"
+"q9" 4 "0 0 0"
+"p9" 4 "0 0 0"
+"o9" 4 "0 0 0"
+"n9" 4 "0 0 0"
+"m9" 4 "0 0 0"
+"l9" 4 "0 0 0"
+"k9" 4 "0 0 0"
+"j9" 4 "0 0 0"
+"i9" 4 "0 0 0"
+"h9" 4 "0 0 0"
+"g9" 4 "0 0 0"
+"f9" 4 "0 0 0"
+"e9" 4 "0 0 0"
+"d9" 4 "0 0 0"
+"c9" 4 "0 0 0"
+"b9" 4 "0 0 0"
+"a9" 4 "0 0 0"
+"a10" 4 "0 0 0"
+"a11" 4 "0 0 0"
+"a12" 4 "0 0 0"
+"a13" 4 "0 0 0"
+"a14" 4 "0 0 0"
+"a15" 4 "0 0 0"
+"a16" 4 "0 0 0"
+"a17" 4 "0 0 0"
+"a18" 4 "0 0 0"
+"a19" 4 "0 0 0"
+"t12" 4 "0 0 0"
+"t11" 4 "0 0 0"
+"t10" 4 "0 0 0"
+"k4" 4 "0 0 0"
+"t3" 4 "0 0 0"
+"s4" 4 "0 0 0"
+"t2" 4 "0 0 0"
+"l5" 4 "0 0 0"
+"j6" 4 "0 0 0"
+"r11" 5 "0 0 0"
+"r6" 4 "0 0 0"
+"r10" 5 "0 0 0"
+"b7" 5 "0 0 0"
+"i6" 4 "0 0 0"
+"a7" 5 "0 0 0"
+"a2" 4 "0 0 0"
+"c4" 5 "0 0 0"
+"b8" 4 "0 0 0"
+"a6" 5 "0 0 0"
+"o6" 4 "0 0 0"
+"p6" 4 "0 0 0"
+"a5" 5 "0 0 0"
+"l7" 4 "0 0 0"
+"l6" 4 "0 0 0"
+"t6" 4 "0 0 0"
+"t5" 4 "0 0 0"
+"b19" 2 "0 0 0"
+"k5" 4 "0 0 0"
+"b18" 2 "0 0 0"
+"p5" 4 "0 0 0"
+"j4" 4 "0 0 0"
+"k15" 1 "0 -1 0"
+"g16" 3 "0 0 0"
+"g12" 3 "0 0 0"
+"l3" 4 "0 0 0"
+"b3" 5 "0 0 0"
+"i5" 4 "0 0 0"
+"c8" 4 "0 0 0"
+"c5" 5 "0 0 0"
+"c6" 5 "0 0 0"
+"a4" 5 "0 0 0"
+"a3" 5 "0 0 0"
+"a8" 4 "0 0 0"
+"c3" 4 "0 0 0"
+"c7" 4 "0 0 0"
+"k6" 5 "0 0 0"
+"d6" 4 "0 0 0"
+"e7" 5 "0 0 0"
+"e6" 5 "0 0 0"
+"s10" 2 "0 0 0"
+"d5" 4 "0 0 0"
+"s11" 2 "0 0 0"
+"d4" 4 "0 0 0"
+"o17" 3 "0 0 0"
+"o13" 3 "0 0 0"
+"l4" 4 "0 0 0"
+"h7" 4 "0 0 0"
+"o4" 4 "0 0 0"
+"p4" 4 "0 0 0"
+"t4" 4 "0 0 0"
+"h6" 4 "0 0 0"
+"h5" 4 "0 0 0"
+"h4" 4 "0 0 0"
+"h3" 4 "0 0 0"
+"f4" 4 "0 0 0"
+"f5" 4 "0 0 0"
+"f6" 4 "0 0 0"
+"n6" 4 "0 0 0"
+"d3" 4 "0 0 0"
+"o5" 4 "0 0 0"
+"n4" 4 "0 0 0"
+"e5" 5 "0 0 0"
+"b2" 4 "0 0 0"
+"c2" 4 "0 0 0"
+"d2" 4 "0 0 0"
+"e2" 4 "0 0 0"
+"f2" 4 "0 0 0"
+"g2" 4 "0 0 0"
+"h2" 4 "0 0 0"
+"i2" 4 "0 0 0"
+"j2" 4 "0 0 0"
+"k2" 4 "0 0 0"
+"l2" 4 "0 0 0"
+"m2" 4 "0 0 0"
+"n2" 4 "0 0 0"
+"o2" 4 "0 0 0"
+"p2" 4 "0 0 0"
+"q2" 4 "0 0 0"
+"r2" 4 "0 0 0"
+"s2" 4 "0 0 0"
+"t1" 4 "0 0 0"
+"s1" 4 "0 0 0"
+"r1" 4 "0 0 0"
+"q1" 4 "0 0 0"
+"p1" 4 "0 0 0"
+"o1" 4 "0 0 0"
+"n1" 4 "0 0 0"
+"m1" 4 "0 0 0"
+"l1" 4 "0 0 0"
+"k1" 4 "0 0 0"
+"j1" 4 "0 0 0"
+"i1" 4 "0 0 0"
+"h1" 4 "0 0 0"
+"g1" 4 "0 0 0"
+"f1" 4 "0 0 0"
+"e1" 4 "0 0 0"
+"d1" 4 "0 0 0"
+"c1" 4 "0 0 0"
+"b1" 4 "0 0 0"
+"a1" 4 "0 0 0"
+"t7" 4 "0 0 0"
+"p3" 4 "0 0 0"
+"p7" 4 "0 0 0"
+"d7" 4 "0 0 0"
+"r3" 4 "0 0 0"
+"e4" 5 "0 0 0"
+"e3" 5 "0 0 0"
+"f3" 5 "0 0 0"
+"d8" 4 "0 0 0"
+"e8" 4 "0 0 0"
+"f8" 4 "0 0 0"
+"g8" 4 "0 0 0"
+"h8" 4 "0 0 0"
+"i8" 4 "0 0 0"
+"j8" 4 "0 0 0"
+"k8" 4 "0 0 0"
+"l8" 4 "0 0 0"
+"m8" 4 "0 0 0"
+"n8" 4 "0 0 0"
+"o8" 4 "0 0 0"
+"p8" 4 "0 0 0"
+"q8" 4 "0 0 0"
+"r8" 4 "0 0 0"
+"s8" 4 "0 0 0"
+"t8" 4 "0 0 0"
+"g3" 5 "0 0 0"
+"g7" 5 "0 0 0"
+"g4" 5 "0 0 0"
+"g6" 5 "0 0 0"
+"g5" 5 "0 0 0"
+"f7" 5 "0 0 0"
+"j5" 5 "0 0 0"
+"i7" 5 "0 0 0"
+"j7" 5 "0 0 0"
+"k7" 5 "0 0 0"
+"i4" 5 "0 0 0"
+"i3" 5 "0 0 0"
+"j3" 5 "0 0 0"
+"k3" 5 "0 0 0"
+"m7" 5 "0 0 0"
+"m6" 5 "0 0 0"
+"m4" 5 "0 0 0"
+"m5" 5 "0 0 0"
+"m3" 5 "0 0 0"
+"n3" 5 "0 0 0"
+"o3" 5 "0 0 0"
+"n5" 5 "0 0 0"
+"n7" 5 "0 0 0"
+"o7" 5 "0 0 0"
+"q7" 5 "0 0 0"
+"q6" 5 "0 0 0"
+"q4" 5 "0 0 0"
+"q5" 5 "0 0 0"
+"q3" 5 "0 0 0"
+"r5" 5 "0 0 0"
+"r4" 5 "0 0 0"
+"s3" 5 "0 0 0"
+"s5" 5 "0 0 0"
+"s6" 5 "0 0 0"
+"s7" 5 "0 0 0"
+"r7" 5 "0 0 0"
+"b6" 4 "0 0 0"
+"b5" 4 "0 0 0"
+"b4" 4 "0 0 0"
--- /dev/null
+// bulldozer storage "level3" last updated 16-11-2015 04:06:54
+nextlevel = "level4"
+"a20" 4 "0 0 0"
+"a19" 4 "0 0 0"
+"f14" 2 "0 0 0"
+"a18" 4 "0 0 0"
+"a17" 4 "0 0 0"
+"a16" 4 "0 0 0"
+"a15" 4 "0 0 0"
+"f14" 3 "0 0 0"
+"b7" 4 "0 0 0"
+"b5" 4 "0 0 0"
+"b3" 4 "0 0 0"
+"s7" 4 "0 0 0"
+"s5" 4 "0 0 0"
+"s3" 4 "0 0 0"
+"b19" 4 "0 0 0"
+"s19" 4 "0 0 0"
+"a14" 4 "0 0 0"
+"a13" 4 "0 0 0"
+"a12" 4 "0 0 0"
+"a11" 4 "0 0 0"
+"a10" 4 "0 0 0"
+"a9" 4 "0 0 0"
+"a8" 4 "0 0 0"
+"a7" 4 "0 0 0"
+"a6" 4 "0 0 0"
+"a5" 4 "0 0 0"
+"a4" 4 "0 0 0"
+"a3" 4 "0 0 0"
+"a2" 4 "0 0 0"
+"a1" 4 "0 0 0"
+"b1" 4 "0 0 0"
+"c1" 4 "0 0 0"
+"d1" 4 "0 0 0"
+"e1" 4 "0 0 0"
+"f1" 4 "0 0 0"
+"g1" 4 "0 0 0"
+"h1" 4 "0 0 0"
+"i1" 4 "0 0 0"
+"j1" 4 "0 0 0"
+"k1" 4 "0 0 0"
+"l1" 4 "0 0 0"
+"m1" 4 "0 0 0"
+"n1" 4 "0 0 0"
+"o1" 4 "0 0 0"
+"p1" 4 "0 0 0"
+"q1" 4 "0 0 0"
+"r1" 4 "0 0 0"
+"s1" 4 "0 0 0"
+"t1" 4 "0 0 0"
+"t2" 4 "0 0 0"
+"t3" 4 "0 0 0"
+"t4" 4 "0 0 0"
+"t5" 4 "0 0 0"
+"t6" 4 "0 0 0"
+"t12" 4 "0 0 0"
+"t9" 4 "0 0 0"
+"t10" 4 "0 0 0"
+"t11" 4 "0 0 0"
+"t7" 4 "0 0 0"
+"t8" 4 "0 0 0"
+"t13" 4 "0 0 0"
+"t14" 4 "0 0 0"
+"t15" 4 "0 0 0"
+"t16" 4 "0 0 0"
+"t17" 4 "0 0 0"
+"t18" 4 "0 0 0"
+"t19" 4 "0 0 0"
+"t20" 4 "0 0 0"
+"r20" 4 "0 0 0"
+"q20" 4 "0 0 0"
+"p20" 4 "0 0 0"
+"s20" 4 "0 0 0"
+"o20" 4 "0 0 0"
+"n20" 4 "0 0 0"
+"m20" 4 "0 0 0"
+"l20" 4 "0 0 0"
+"k20" 4 "0 0 0"
+"j20" 4 "0 0 0"
+"i20" 4 "0 0 0"
+"h20" 4 "0 0 0"
+"g20" 4 "0 0 0"
+"f20" 4 "0 0 0"
+"e20" 4 "0 0 0"
+"d20" 4 "0 0 0"
+"c20" 4 "0 0 0"
+"b20" 4 "0 0 0"
+"c19" 4 "0 0 0"
+"b18" 4 "0 0 0"
+"b16" 4 "0 0 0"
+"c18" 4 "0 0 0"
+"b14" 4 "0 0 0"
+"b17" 7 "0 0 0"
+"b12" 4 "0 0 0"
+"b15" 7 "0 0 0"
+"b9" 7 "0 0 0"
+"b8" 4 "0 0 0"
+"b11" 7 "0 0 0"
+"b10" 4 "0 0 0"
+"b6" 4 "0 0 0"
+"b13" 7 "0 0 0"
+"b2" 4 "0 0 0"
+"b4" 4 "0 0 0"
+"s18" 4 "0 0 0"
+"s13" 7 "0 0 0"
+"s16" 4 "0 0 0"
+"s11" 7 "0 0 0"
+"s14" 4 "0 0 0"
+"s9" 7 "0 0 0"
+"s12" 4 "0 0 0"
+"s8" 4 "0 0 0"
+"s6" 4 "0 0 0"
+"s4" 4 "0 0 0"
+"s2" 4 "0 0 0"
+"s10" 4 "0 0 0"
+"s17" 7 "0 0 0"
+"s15" 7 "0 0 0"
+"c7" 4 "0 0 0"
+"c6" 4 "0 0 0"
+"d7" 4 "0 0 0"
+"f7" 4 "0 0 0"
+"e7" 4 "0 0 0"
+"g7" 4 "0 0 0"
+"h7" 4 "0 0 0"
+"i7" 4 "0 0 0"
+"j7" 4 "0 0 0"
+"k7" 4 "0 0 0"
+"l7" 4 "0 0 0"
+"m7" 4 "0 0 0"
+"n7" 4 "0 0 0"
+"o7" 4 "0 0 0"
+"p7" 4 "0 0 0"
+"q7" 4 "0 0 0"
+"r7" 4 "0 0 0"
+"h4" 4 "0 0 0"
+"g4" 4 "0 0 0"
+"f4" 4 "0 0 0"
+"e4" 4 "0 0 0"
+"d4" 4 "0 0 0"
+"c4" 4 "0 0 0"
+"c3" 4 "0 0 0"
+"d3" 4 "0 0 0"
+"e3" 4 "0 0 0"
+"f3" 4 "0 0 0"
+"g3" 4 "0 0 0"
+"h3" 4 "0 0 0"
+"i3" 4 "0 0 0"
+"j3" 4 "0 0 0"
+"k3" 4 "0 0 0"
+"l3" 4 "0 0 0"
+"m3" 4 "0 0 0"
+"n3" 4 "0 0 0"
+"o3" 4 "0 0 0"
+"p3" 4 "0 0 0"
+"q3" 4 "0 0 0"
+"r3" 4 "0 0 0"
+"r2" 4 "0 0 0"
+"q2" 4 "0 0 0"
+"p2" 4 "0 0 0"
+"o2" 4 "0 0 0"
+"n2" 4 "0 0 0"
+"m2" 4 "0 0 0"
+"l2" 4 "0 0 0"
+"k2" 4 "0 0 0"
+"j2" 4 "0 0 0"
+"i2" 4 "0 0 0"
+"h2" 4 "0 0 0"
+"g2" 4 "0 0 0"
+"f2" 4 "0 0 0"
+"e2" 4 "0 0 0"
+"d2" 4 "0 0 0"
+"c2" 4 "0 0 0"
+"r4" 4 "0 0 0"
+"q4" 4 "0 0 0"
+"p4" 4 "0 0 0"
+"o4" 4 "0 0 0"
+"n4" 4 "0 0 0"
+"m4" 4 "0 0 0"
+"l4" 4 "0 0 0"
+"k4" 4 "0 0 0"
+"j4" 4 "0 0 0"
+"i4" 4 "0 0 0"
+"i5" 4 "0 0 0"
+"h5" 4 "0 0 0"
+"g5" 4 "0 0 0"
+"f5" 4 "0 0 0"
+"e5" 4 "0 0 0"
+"d5" 4 "0 0 0"
+"c5" 4 "0 0 0"
+"d6" 4 "0 0 0"
+"e6" 4 "0 0 0"
+"f6" 4 "0 0 0"
+"g6" 4 "0 0 0"
+"h6" 4 "0 0 0"
+"i6" 4 "0 0 0"
+"j6" 4 "0 0 0"
+"k6" 4 "0 0 0"
+"l6" 4 "0 0 0"
+"m6" 4 "0 0 0"
+"n6" 4 "0 0 0"
+"o6" 4 "0 0 0"
+"p6" 4 "0 0 0"
+"q6" 4 "0 0 0"
+"r6" 4 "0 0 0"
+"r5" 4 "0 0 0"
+"q5" 4 "0 0 0"
+"p5" 4 "0 0 0"
+"o5" 4 "0 0 0"
+"n5" 4 "0 0 0"
+"m5" 4 "0 0 0"
+"l5" 4 "0 0 0"
+"k5" 4 "0 0 0"
+"j5" 4 "0 0 0"
+"d18" 4 "0 0 0"
+"e18" 4 "0 0 0"
+"g18" 4 "0 0 0"
+"h18" 4 "0 0 0"
+"f18" 4 "0 0 0"
+"j18" 4 "0 0 0"
+"i18" 4 "0 0 0"
+"k18" 4 "0 0 0"
+"m18" 4 "0 0 0"
+"l18" 4 "0 0 0"
+"n18" 4 "0 0 0"
+"o18" 4 "0 0 0"
+"p18" 4 "0 0 0"
+"q18" 4 "0 0 0"
+"r18" 4 "0 0 0"
+"q19" 4 "0 0 0"
+"p19" 4 "0 0 0"
+"o19" 4 "0 0 0"
+"n19" 4 "0 0 0"
+"m19" 4 "0 0 0"
+"l19" 4 "0 0 0"
+"k19" 4 "0 0 0"
+"j19" 4 "0 0 0"
+"i19" 4 "0 0 0"
+"h19" 4 "0 0 0"
+"g19" 4 "0 0 0"
+"f19" 4 "0 0 0"
+"e19" 4 "0 0 0"
+"d19" 4 "0 0 0"
+"r19" 4 "0 0 0"
+"f15" 5 "0 0 0"
+"f13" 5 "0 0 0"
+"f12" 5 "0 0 0"
+"g12" 5 "0 0 0"
+"g9" 5 "0 0 0"
+"g10" 5 "0 0 0"
+"g11" 5 "0 0 0"
+"h9" 5 "0 0 0"
+"i9" 5 "0 0 0"
+"k9" 5 "0 0 0"
+"l9" 5 "0 0 0"
+"l13" 5 "0 0 0"
+"l12" 5 "0 0 0"
+"l10" 5 "0 0 0"
+"l11" 5 "0 0 0"
+"l15" 5 "0 0 0"
+"l14" 5 "0 0 0"
+"l16" 5 "0 0 0"
+"g15" 5 "0 0 0"
+"h15" 5 "0 0 0"
+"i15" 5 "0 0 0"
+"j15" 5 "0 0 0"
+"k15" 5 "0 0 0"
+"p9" 5 "0 0 0"
+"p10" 5 "0 0 0"
+"q10" 5 "0 0 0"
+"q8" 2 "0 0 0"
+"r8" 2 "0 0 0"
+"r9" 2 "0 0 0"
+"j9" 3 "0 0 0"
+"i13" 2 "0 0 0"
+"k13" 1 "0 -1 0"
+"n13" 3 "0 0 0"
+"n14" 3 "0 0 0"
+"n12" 3 "0 0 0"
--- /dev/null
+// bulldozer storage "level4" last updated 16-11-2015 05:09:50
+nextlevel = "level5"
+"k10" 9 "0 -1 0"
+"k11" 9 "0 -1 0"
+"k13" 9 "0 -1 0"
+"j14" 9 "0 -1 0"
+"k14" 9 "0 -1 0"
+"k8" 5 "0 -1 0"
+"k9" 5 "0 -1 0"
+"k7" 5 "0 -1 0"
+"m8" 4 "0 -1 0"
+"l14" 9 "0 -1 0"
+"i14" 9 "0 -1 0"
+"m12" 1 "0 -1 0"
+"l11" 2 "0 -1 0"
+"m11" 2 "0 -1 0"
+"m10" 2 "0 -1 0"
+"l10" 2 "0 -1 0"
+"k12" 3 "0 -1 0"
+"m16" 5 "0 -1 0"
+"l16" 5 "0 -1 0"
+"k16" 5 "0 -1 0"
+"j4" 4 "0 -1 0"
+"i4" 4 "0 -1 0"
+"h4" 4 "0 -1 0"
+"g4" 4 "0 -1 0"
+"f4" 4 "0 -1 0"
+"e4" 4 "0 -1 0"
+"d4" 4 "0 -1 0"
+"c4" 4 "0 -1 0"
+"b4" 4 "0 -1 0"
+"h11" 3 "0 -1 0"
+"f20" 4 "0 -1 0"
+"f19" 4 "0 -1 0"
+"f17" 4 "0 -1 0"
+"f18" 4 "0 -1 0"
+"h16" 5 "0 -1 0"
+"f16" 4 "0 -1 0"
+"f15" 4 "0 -1 0"
+"f14" 5 "0 -1 0"
+"g14" 5 "0 -1 0"
+"e13" 4 "0 -1 0"
+"e12" 4 "0 -1 0"
+"e11" 4 "0 -1 0"
+"e10" 4 "0 -1 0"
+"e9" 4 "0 -1 0"
+"e8" 4 "0 -1 0"
+"e7" 4 "0 -1 0"
+"f9" 5 "0 -1 0"
+"f7" 5 "0 -1 0"
+"f8" 5 "0 -1 0"
+"f10" 5 "0 -1 0"
+"g7" 5 "0 -1 0"
+"h12" 3 "0 -1 0"
+"m14" 3 "0 -1 0"
+"a4" 4 "0 -1 0"
+"a3" 4 "0 -1 0"
+"b3" 4 "0 -1 0"
+"c3" 4 "0 -1 0"
+"d3" 4 "0 -1 0"
+"e3" 4 "0 -1 0"
+"f3" 4 "0 -1 0"
+"g3" 4 "0 -1 0"
+"h3" 4 "0 -1 0"
+"i3" 4 "0 -1 0"
+"j3" 4 "0 -1 0"
+"k3" 4 "0 -1 0"
+"l3" 4 "0 -1 0"
+"m3" 4 "0 -1 0"
+"n3" 4 "0 -1 0"
+"o3" 4 "0 -1 0"
+"p3" 4 "0 -1 0"
+"q3" 4 "0 -1 0"
+"r3" 4 "0 -1 0"
+"s3" 4 "0 -1 0"
+"t3" 4 "0 -1 0"
+"t2" 4 "0 -1 0"
+"s2" 4 "0 -1 0"
+"r2" 4 "0 -1 0"
+"q2" 4 "0 -1 0"
+"p2" 4 "0 -1 0"
+"o2" 4 "0 -1 0"
+"n2" 4 "0 -1 0"
+"m2" 4 "0 -1 0"
+"l2" 4 "0 -1 0"
+"k2" 4 "0 -1 0"
+"j2" 4 "0 -1 0"
+"i2" 4 "0 -1 0"
+"h2" 4 "0 -1 0"
+"g2" 4 "0 -1 0"
+"f2" 4 "0 -1 0"
+"e2" 4 "0 -1 0"
+"d2" 4 "0 -1 0"
+"c2" 4 "0 -1 0"
+"b2" 4 "0 -1 0"
+"a2" 4 "0 -1 0"
+"a1" 4 "0 -1 0"
+"b1" 4 "0 -1 0"
+"c1" 4 "0 -1 0"
+"d1" 4 "0 -1 0"
+"e1" 4 "0 -1 0"
+"f1" 4 "0 -1 0"
+"g1" 4 "0 -1 0"
+"h1" 4 "0 -1 0"
+"i1" 4 "0 -1 0"
+"j1" 4 "0 -1 0"
+"k1" 4 "0 -1 0"
+"l1" 4 "0 -1 0"
+"m1" 4 "0 -1 0"
+"n1" 4 "0 -1 0"
+"o1" 4 "0 -1 0"
+"p1" 4 "0 -1 0"
+"q1" 4 "0 -1 0"
+"r1" 4 "0 -1 0"
+"s1" 4 "0 -1 0"
+"t1" 4 "0 -1 0"
+"t4" 4 "0 -1 0"
+"s4" 4 "0 -1 0"
+"r4" 4 "0 -1 0"
+"q4" 4 "0 -1 0"
+"p4" 4 "0 -1 0"
+"o4" 4 "0 -1 0"
+"n4" 4 "0 -1 0"
+"m4" 4 "0 -1 0"
+"l4" 4 "0 -1 0"
+"k4" 4 "0 -1 0"
+"k5" 4 "0 -1 0"
+"j5" 4 "0 -1 0"
+"i5" 4 "0 -1 0"
+"h5" 4 "0 -1 0"
+"g5" 4 "0 -1 0"
+"f5" 4 "0 -1 0"
+"e5" 4 "0 -1 0"
+"d5" 4 "0 -1 0"
+"c5" 4 "0 -1 0"
+"b5" 4 "0 -1 0"
+"a5" 4 "0 -1 0"
+"a6" 4 "0 -1 0"
+"b6" 4 "0 -1 0"
+"c6" 4 "0 -1 0"
+"d6" 4 "0 -1 0"
+"e6" 4 "0 -1 0"
+"f6" 4 "0 -1 0"
+"g6" 4 "0 -1 0"
+"h6" 4 "0 -1 0"
+"i6" 4 "0 -1 0"
+"j6" 4 "0 -1 0"
+"k6" 4 "0 -1 0"
+"l6" 4 "0 -1 0"
+"m6" 4 "0 -1 0"
+"n6" 4 "0 -1 0"
+"o6" 4 "0 -1 0"
+"p6" 4 "0 -1 0"
+"q6" 4 "0 -1 0"
+"r6" 4 "0 -1 0"
+"s6" 4 "0 -1 0"
+"t6" 4 "0 -1 0"
+"t5" 4 "0 -1 0"
+"s5" 4 "0 -1 0"
+"r5" 4 "0 -1 0"
+"q5" 4 "0 -1 0"
+"p5" 4 "0 -1 0"
+"o5" 4 "0 -1 0"
+"n5" 4 "0 -1 0"
+"m5" 4 "0 -1 0"
+"l5" 4 "0 -1 0"
+"t7" 4 "0 -1 0"
+"s7" 4 "0 -1 0"
+"r7" 4 "0 -1 0"
+"s8" 8 "0 -1 0"
+"p7" 4 "0 -1 0"
+"o7" 4 "0 -1 0"
+"n7" 4 "0 -1 0"
+"m7" 4 "0 -1 0"
+"l7" 4 "0 -1 0"
+"j7" 5 "0 -1 0"
+"i7" 5 "0 -1 0"
+"l8" 4 "0 -1 0"
+"n8" 4 "0 -1 0"
+"o8" 4 "0 -1 0"
+"p8" 4 "0 -1 0"
+"q8" 4 "0 -1 0"
+"r8" 4 "0 -1 0"
+"s12" 8 "0 -1 0"
+"t8" 4 "0 -1 0"
+"t9" 4 "0 -1 0"
+"s9" 4 "0 -1 0"
+"r9" 4 "0 -1 0"
+"q7" 8 "0 -1 0"
+"p9" 4 "0 -1 0"
+"o9" 4 "0 -1 0"
+"m9" 5 "0 -1 0"
+"n9" 5 "0 -1 0"
+"o10" 4 "0 -1 0"
+"p10" 4 "0 -1 0"
+"q10" 4 "0 -1 0"
+"r10" 4 "0 -1 0"
+"s14" 8 "0 -1 0"
+"t10" 4 "0 -1 0"
+"t11" 4 "0 -1 0"
+"s11" 4 "0 -1 0"
+"r11" 4 "0 -1 0"
+"q9" 8 "0 -1 0"
+"p11" 4 "0 -1 0"
+"o11" 4 "0 -1 0"
+"n10" 5 "0 -1 0"
+"n11" 5 "0 -1 0"
+"o12" 4 "0 -1 0"
+"p12" 4 "0 -1 0"
+"q12" 4 "0 -1 0"
+"r12" 4 "0 -1 0"
+"t12" 4 "0 -1 0"
+"t13" 4 "0 -1 0"
+"s13" 4 "0 -1 0"
+"r13" 4 "0 -1 0"
+"q11" 8 "0 -1 0"
+"p13" 4 "0 -1 0"
+"o13" 4 "0 -1 0"
+"l9" 5 "0 -1 0"
+"n12" 5 "0 -1 0"
+"o14" 4 "0 -1 0"
+"p14" 4 "0 -1 0"
+"q14" 4 "0 -1 0"
+"r14" 4 "0 -1 0"
+"f12" 5 "0 -1 0"
+"t14" 4 "0 -1 0"
+"t15" 4 "0 -1 0"
+"s15" 4 "0 -1 0"
+"r15" 4 "0 -1 0"
+"q15" 8 "0 -1 0"
+"p15" 4 "0 -1 0"
+"o15" 4 "0 -1 0"
+"n13" 5 "0 -1 0"
+"n16" 5 "0 -1 0"
+"o16" 4 "0 -1 0"
+"p16" 4 "0 -1 0"
+"q16" 4 "0 -1 0"
+"r16" 4 "0 -1 0"
+"q13" 8 "0 -1 0"
+"t16" 4 "0 -1 0"
+"t17" 4 "0 -1 0"
+"s17" 4 "0 -1 0"
+"r17" 4 "0 -1 0"
+"q17" 4 "0 -1 0"
+"p17" 4 "0 -1 0"
+"o17" 4 "0 -1 0"
+"n17" 4 "0 -1 0"
+"m17" 4 "0 -1 0"
+"l17" 4 "0 -1 0"
+"k17" 4 "0 -1 0"
+"j17" 4 "0 -1 0"
+"i17" 4 "0 -1 0"
+"h17" 4 "0 -1 0"
+"g17" 4 "0 -1 0"
+"g18" 4 "0 -1 0"
+"h18" 4 "0 -1 0"
+"i18" 4 "0 -1 0"
+"j18" 4 "0 -1 0"
+"k18" 4 "0 -1 0"
+"l18" 4 "0 -1 0"
+"m18" 4 "0 -1 0"
+"n18" 4 "0 -1 0"
+"o18" 4 "0 -1 0"
+"p18" 4 "0 -1 0"
+"q18" 4 "0 -1 0"
+"r18" 4 "0 -1 0"
+"s18" 4 "0 -1 0"
+"t18" 4 "0 -1 0"
+"t19" 4 "0 -1 0"
+"s19" 4 "0 -1 0"
+"r19" 4 "0 -1 0"
+"q19" 4 "0 -1 0"
+"p19" 4 "0 -1 0"
+"o19" 4 "0 -1 0"
+"n19" 4 "0 -1 0"
+"m19" 4 "0 -1 0"
+"l19" 4 "0 -1 0"
+"k19" 4 "0 -1 0"
+"j19" 4 "0 -1 0"
+"i19" 4 "0 -1 0"
+"h19" 4 "0 -1 0"
+"g19" 4 "0 -1 0"
+"g20" 4 "0 -1 0"
+"h20" 4 "0 -1 0"
+"i20" 4 "0 -1 0"
+"j20" 4 "0 -1 0"
+"k20" 4 "0 -1 0"
+"l20" 4 "0 -1 0"
+"m20" 4 "0 -1 0"
+"n20" 4 "0 -1 0"
+"o20" 4 "0 -1 0"
+"p20" 4 "0 -1 0"
+"q20" 4 "0 -1 0"
+"r20" 4 "0 -1 0"
+"s20" 4 "0 -1 0"
+"t20" 4 "0 -1 0"
+"d7" 4 "0 -1 0"
+"c7" 4 "0 -1 0"
+"b7" 4 "0 -1 0"
+"a9" 8 "0 -1 0"
+"a8" 4 "0 -1 0"
+"b8" 4 "0 -1 0"
+"a7" 8 "0 -1 0"
+"d8" 4 "0 -1 0"
+"d9" 4 "0 -1 0"
+"c9" 4 "0 -1 0"
+"b9" 4 "0 -1 0"
+"a13" 8 "0 -1 0"
+"a10" 4 "0 -1 0"
+"b10" 4 "0 -1 0"
+"a11" 8 "0 -1 0"
+"d10" 4 "0 -1 0"
+"d11" 4 "0 -1 0"
+"c11" 4 "0 -1 0"
+"b11" 4 "0 -1 0"
+"a15" 8 "0 -1 0"
+"a12" 4 "0 -1 0"
+"b12" 4 "0 -1 0"
+"c10" 8 "0 -1 0"
+"d12" 4 "0 -1 0"
+"d13" 4 "0 -1 0"
+"c13" 4 "0 -1 0"
+"b13" 4 "0 -1 0"
+"s16" 8 "0 -1 0"
+"a14" 4 "0 -1 0"
+"b14" 4 "0 -1 0"
+"c12" 8 "0 -1 0"
+"d14" 4 "0 -1 0"
+"e14" 4 "0 -1 0"
+"e15" 4 "0 -1 0"
+"d15" 4 "0 -1 0"
+"c15" 4 "0 -1 0"
+"b15" 4 "0 -1 0"
+"s10" 8 "0 -1 0"
+"a16" 4 "0 -1 0"
+"b16" 4 "0 -1 0"
+"c16" 8 "0 -1 0"
+"d16" 4 "0 -1 0"
+"e16" 4 "0 -1 0"
+"e17" 4 "0 -1 0"
+"d17" 4 "0 -1 0"
+"c17" 4 "0 -1 0"
+"b17" 4 "0 -1 0"
+"a17" 4 "0 -1 0"
+"a18" 4 "0 -1 0"
+"b18" 4 "0 -1 0"
+"c18" 4 "0 -1 0"
+"d18" 4 "0 -1 0"
+"e18" 4 "0 -1 0"
+"e19" 4 "0 -1 0"
+"d19" 4 "0 -1 0"
+"c19" 4 "0 -1 0"
+"b19" 4 "0 -1 0"
+"a19" 4 "0 -1 0"
+"a20" 4 "0 -1 0"
+"b20" 4 "0 -1 0"
+"c20" 4 "0 -1 0"
+"d20" 4 "0 -1 0"
+"e20" 4 "0 -1 0"
+"f11" 5 "0 -1 0"
+"c14" 8 "0 -1 0"
+"c8" 8 "0 -1 0"
+"f13" 5 "0 -1 0"
+"g15" 5 "0 -1 0"
+"g16" 5 "0 -1 0"
+"i16" 5 "0 -1 0"
+"j16" 5 "0 -1 0"
+"n15" 5 "0 -1 0"
+"n14" 5 "0 -1 0"
+"h7" 5 "0 -1 0"
--- /dev/null
+// bulldozer storage "level5" last updated 17-11-2015 21:42:14
+nextlevel = "level6"
+"a7" 4 "0 -1 0"
+"c18" 6 "0 -1 0"
+"a19" 4 "0 -1 0"
+"d17" 6 "0 -1 0"
+"c19" 4 "0 -1 0"
+"d19" 4 "0 -1 0"
+"e19" 4 "0 -1 0"
+"f19" 4 "0 -1 0"
+"g19" 4 "0 -1 0"
+"h19" 4 "0 -1 0"
+"i19" 4 "0 -1 0"
+"j19" 4 "0 -1 0"
+"k19" 4 "0 -1 0"
+"l19" 4 "0 -1 0"
+"m19" 4 "0 -1 0"
+"n19" 4 "0 -1 0"
+"o19" 4 "0 -1 0"
+"p19" 4 "0 -1 0"
+"q19" 4 "0 -1 0"
+"r19" 4 "0 -1 0"
+"q17" 6 "0 -1 0"
+"t19" 4 "0 -1 0"
+"e10" 4 "0 -1 0"
+"e18" 4 "0 -1 0"
+"p8" 4 "0 -1 0"
+"e17" 4 "0 -1 0"
+"e16" 4 "0 -1 0"
+"e8" 4 "0 -1 0"
+"e9" 4 "0 -1 0"
+"e15" 4 "0 -1 0"
+"e13" 4 "0 -1 0"
+"e12" 4 "0 -1 0"
+"e11" 4 "0 -1 0"
+"e7" 4 "0 -1 0"
+"d7" 4 "0 -1 0"
+"c7" 4 "0 -1 0"
+"b7" 4 "0 -1 0"
+"e14" 4 "0 -1 0"
+"f17" 4 "0 -1 0"
+"o7" 4 "0 -1 0"
+"f6" 4 "0 -1 0"
+"i6" 4 "0 -1 0"
+"g6" 4 "0 -1 0"
+"h6" 4 "0 -1 0"
+"k6" 4 "0 -1 0"
+"j6" 4 "0 -1 0"
+"l6" 4 "0 -1 0"
+"m6" 4 "0 -1 0"
+"p7" 4 "0 -1 0"
+"p9" 4 "0 -1 0"
+"p10" 4 "0 -1 0"
+"p11" 4 "0 -1 0"
+"p12" 4 "0 -1 0"
+"p13" 4 "0 -1 0"
+"p14" 4 "0 -1 0"
+"o15" 4 "0 -1 0"
+"p16" 4 "0 -1 0"
+"p17" 4 "0 -1 0"
+"p18" 4 "0 -1 0"
+"q7" 4 "0 -1 0"
+"r7" 4 "0 -1 0"
+"s7" 4 "0 -1 0"
+"t7" 4 "0 -1 0"
+"c13" 4 "0 -1 0"
+"b13" 4 "0 -1 0"
+"a13" 4 "0 -1 0"
+"a12" 4 "0 -1 0"
+"b12" 4 "0 -1 0"
+"c12" 4 "0 -1 0"
+"d12" 4 "0 -1 0"
+"d11" 4 "0 -1 0"
+"c11" 4 "0 -1 0"
+"b11" 4 "0 -1 0"
+"a11" 4 "0 -1 0"
+"a10" 4 "0 -1 0"
+"b10" 4 "0 -1 0"
+"c10" 4 "0 -1 0"
+"d10" 4 "0 -1 0"
+"d9" 4 "0 -1 0"
+"c9" 4 "0 -1 0"
+"b9" 4 "0 -1 0"
+"a9" 4 "0 -1 0"
+"a8" 4 "0 -1 0"
+"b8" 4 "0 -1 0"
+"c8" 4 "0 -1 0"
+"d8" 4 "0 -1 0"
+"d13" 4 "0 -1 0"
+"d14" 4 "0 -1 0"
+"c14" 4 "0 -1 0"
+"b14" 4 "0 -1 0"
+"a14" 4 "0 -1 0"
+"a15" 4 "0 -1 0"
+"b15" 4 "0 -1 0"
+"c15" 4 "0 -1 0"
+"d15" 4 "0 -1 0"
+"d16" 4 "0 -1 0"
+"c16" 4 "0 -1 0"
+"b16" 4 "0 -1 0"
+"a16" 4 "0 -1 0"
+"a17" 4 "0 -1 0"
+"b17" 4 "0 -1 0"
+"c17" 4 "0 -1 0"
+"a1" 6 "0 -1 0"
+"d18" 4 "0 -1 0"
+"b2" 6 "0 -1 0"
+"b18" 4 "0 -1 0"
+"a18" 4 "0 -1 0"
+"f20" 4 "0 -1 0"
+"e20" 4 "0 -1 0"
+"d20" 4 "0 -1 0"
+"c20" 4 "0 -1 0"
+"b20" 4 "0 -1 0"
+"g20" 4 "0 -1 0"
+"h20" 4 "0 -1 0"
+"i20" 4 "0 -1 0"
+"j20" 4 "0 -1 0"
+"k20" 4 "0 -1 0"
+"l20" 4 "0 -1 0"
+"m20" 4 "0 -1 0"
+"n20" 4 "0 -1 0"
+"o20" 4 "0 -1 0"
+"p20" 4 "0 -1 0"
+"q20" 4 "0 -1 0"
+"r20" 4 "0 -1 0"
+"s20" 4 "0 -1 0"
+"r18" 6 "0 -1 0"
+"s13" 4 "0 -1 0"
+"r13" 4 "0 -1 0"
+"q13" 4 "0 -1 0"
+"q12" 4 "0 -1 0"
+"r12" 4 "0 -1 0"
+"s12" 4 "0 -1 0"
+"t12" 4 "0 -1 0"
+"t11" 4 "0 -1 0"
+"s11" 4 "0 -1 0"
+"r11" 4 "0 -1 0"
+"q11" 4 "0 -1 0"
+"q10" 4 "0 -1 0"
+"r10" 4 "0 -1 0"
+"s10" 4 "0 -1 0"
+"t10" 4 "0 -1 0"
+"t9" 4 "0 -1 0"
+"s9" 4 "0 -1 0"
+"r9" 4 "0 -1 0"
+"q9" 4 "0 -1 0"
+"q8" 4 "0 -1 0"
+"r8" 4 "0 -1 0"
+"s8" 4 "0 -1 0"
+"t8" 4 "0 -1 0"
+"t13" 4 "0 -1 0"
+"t14" 4 "0 -1 0"
+"s14" 4 "0 -1 0"
+"r14" 4 "0 -1 0"
+"q14" 4 "0 -1 0"
+"q15" 4 "0 -1 0"
+"r15" 4 "0 -1 0"
+"s15" 4 "0 -1 0"
+"t15" 4 "0 -1 0"
+"t16" 4 "0 -1 0"
+"s16" 4 "0 -1 0"
+"r16" 4 "0 -1 0"
+"q16" 4 "0 -1 0"
+"g15" 1 "0 -1 0"
+"r17" 4 "0 -1 0"
+"s17" 4 "0 -1 0"
+"t17" 4 "0 -1 0"
+"t18" 4 "0 -1 0"
+"s18" 4 "0 -1 0"
+"m13" 2 "0 -1 0"
+"q18" 4 "0 -1 0"
+"g3" 4 "0 -1 0"
+"f3" 4 "0 -1 0"
+"e3" 4 "0 -1 0"
+"d3" 4 "0 -1 0"
+"t1" 6 "0 -1 0"
+"b3" 4 "0 -1 0"
+"a3" 4 "0 -1 0"
+"a2" 4 "0 -1 0"
+"d4" 6 "0 -1 0"
+"c2" 4 "0 -1 0"
+"d2" 4 "0 -1 0"
+"e2" 4 "0 -1 0"
+"f2" 4 "0 -1 0"
+"g2" 4 "0 -1 0"
+"h2" 4 "0 -1 0"
+"i2" 4 "0 -1 0"
+"j2" 4 "0 -1 0"
+"k2" 4 "0 -1 0"
+"l2" 4 "0 -1 0"
+"m2" 4 "0 -1 0"
+"n2" 4 "0 -1 0"
+"o2" 4 "0 -1 0"
+"p2" 4 "0 -1 0"
+"q2" 4 "0 -1 0"
+"r2" 4 "0 -1 0"
+"q4" 6 "0 -1 0"
+"t2" 4 "0 -1 0"
+"r3" 6 "0 -1 0"
+"s1" 4 "0 -1 0"
+"r1" 4 "0 -1 0"
+"q1" 4 "0 -1 0"
+"p1" 4 "0 -1 0"
+"o1" 4 "0 -1 0"
+"n1" 4 "0 -1 0"
+"m1" 4 "0 -1 0"
+"l1" 4 "0 -1 0"
+"k1" 4 "0 -1 0"
+"j1" 4 "0 -1 0"
+"i1" 4 "0 -1 0"
+"h1" 4 "0 -1 0"
+"g1" 4 "0 -1 0"
+"f1" 4 "0 -1 0"
+"e1" 4 "0 -1 0"
+"d1" 4 "0 -1 0"
+"c1" 4 "0 -1 0"
+"b1" 4 "0 -1 0"
+"c3" 6 "0 -1 0"
+"t3" 4 "0 -1 0"
+"s3" 4 "0 -1 0"
+"t20" 6 "0 -1 0"
+"q3" 4 "0 -1 0"
+"p3" 4 "0 -1 0"
+"o3" 4 "0 -1 0"
+"n3" 4 "0 -1 0"
+"m3" 4 "0 -1 0"
+"l3" 4 "0 -1 0"
+"k3" 4 "0 -1 0"
+"j3" 4 "0 -1 0"
+"i3" 4 "0 -1 0"
+"h3" 4 "0 -1 0"
+"h4" 4 "0 -1 0"
+"g4" 4 "0 -1 0"
+"f4" 4 "0 -1 0"
+"e4" 4 "0 -1 0"
+"s2" 6 "0 -1 0"
+"c4" 4 "0 -1 0"
+"b4" 4 "0 -1 0"
+"a4" 4 "0 -1 0"
+"a5" 4 "0 -1 0"
+"b5" 4 "0 -1 0"
+"c5" 4 "0 -1 0"
+"d5" 4 "0 -1 0"
+"e5" 4 "0 -1 0"
+"f5" 4 "0 -1 0"
+"g5" 4 "0 -1 0"
+"h5" 4 "0 -1 0"
+"i5" 4 "0 -1 0"
+"j5" 4 "0 -1 0"
+"k5" 4 "0 -1 0"
+"l5" 4 "0 -1 0"
+"m5" 4 "0 -1 0"
+"n5" 4 "0 -1 0"
+"o5" 4 "0 -1 0"
+"p5" 4 "0 -1 0"
+"q5" 4 "0 -1 0"
+"r5" 4 "0 -1 0"
+"s5" 4 "0 -1 0"
+"t5" 4 "0 -1 0"
+"t4" 4 "0 -1 0"
+"s4" 4 "0 -1 0"
+"r4" 4 "0 -1 0"
+"s19" 6 "0 -1 0"
+"p4" 4 "0 -1 0"
+"o4" 4 "0 -1 0"
+"n4" 4 "0 -1 0"
+"m4" 4 "0 -1 0"
+"l4" 4 "0 -1 0"
+"k4" 4 "0 -1 0"
+"j4" 4 "0 -1 0"
+"i4" 4 "0 -1 0"
+"t6" 4 "0 -1 0"
+"s6" 4 "0 -1 0"
+"r6" 4 "0 -1 0"
+"q6" 4 "0 -1 0"
+"p6" 4 "0 -1 0"
+"o6" 4 "0 -1 0"
+"n6" 4 "0 -1 0"
+"n7" 4 "0 -1 0"
+"l7" 4 "0 -1 0"
+"j7" 4 "0 -1 0"
+"h7" 4 "0 -1 0"
+"f7" 4 "0 -1 0"
+"g7" 4 "0 -1 0"
+"i7" 4 "0 -1 0"
+"k7" 4 "0 -1 0"
+"e6" 4 "0 -1 0"
+"d6" 4 "0 -1 0"
+"c6" 4 "0 -1 0"
+"b6" 4 "0 -1 0"
+"a6" 4 "0 -1 0"
+"p15" 4 "0 -1 0"
+"m7" 4 "0 -1 0"
+"f16" 5 "0 -1 0"
+"f13" 5 "0 -1 0"
+"f15" 5 "0 -1 0"
+"f14" 5 "0 -1 0"
+"f12" 5 "0 -1 0"
+"g12" 5 "0 -1 0"
+"h12" 5 "0 -1 0"
+"h11" 5 "0 -1 0"
+"g9" 5 "0 -1 0"
+"g8" 5 "0 -1 0"
+"g11" 5 "0 -1 0"
+"g10" 5 "0 -1 0"
+"h8" 5 "0 -1 0"
+"i8" 5 "0 -1 0"
+"j8" 5 "0 -1 0"
+"k8" 5 "0 -1 0"
+"k9" 5 "0 -1 0"
+"k10" 5 "0 -1 0"
+"l9" 5 "0 -1 0"
+"m9" 5 "0 -1 0"
+"n9" 5 "0 -1 0"
+"n10" 5 "0 -1 0"
+"n11" 5 "0 -1 0"
+"n12" 5 "0 -1 0"
+"n13" 5 "0 -1 0"
+"n14" 5 "0 -1 0"
+"m14" 5 "0 -1 0"
+"l14" 5 "0 -1 0"
+"j17" 4 "0 -1 0"
+"j18" 4 "0 -1 0"
+"i18" 4 "0 -1 0"
+"h18" 4 "0 -1 0"
+"g18" 4 "0 -1 0"
+"f18" 4 "0 -1 0"
+"l13" 5 "0 -1 0"
+"l12" 5 "0 -1 0"
+"k12" 5 "0 -1 0"
+"j12" 5 "0 -1 0"
+"j13" 5 "0 -1 0"
+"j15" 5 "0 -1 0"
+"j14" 5 "0 -1 0"
+"j16" 5 "0 -1 0"
+"i16" 5 "0 -1 0"
+"h16" 5 "0 -1 0"
+"g16" 5 "0 -1 0"
+"f10" 4 "0 -1 0"
+"f9" 4 "0 -1 0"
+"f8" 4 "0 -1 0"
+"f11" 4 "0 -1 0"
+"o9" 4 "0 -1 0"
+"o8" 4 "0 -1 0"
+"m8" 4 "0 -1 0"
+"l8" 4 "0 -1 0"
+"n8" 4 "0 -1 0"
+"m15" 4 "0 -1 0"
+"l15" 4 "0 -1 0"
+"k15" 4 "0 -1 0"
+"o10" 4 "0 -1 0"
+"k14" 4 "0 -1 0"
+"k13" 4 "0 -1 0"
+"k16" 4 "0 -1 0"
+"o11" 4 "0 -1 0"
+"o12" 4 "0 -1 0"
+"o13" 4 "0 -1 0"
+"o14" 4 "0 -1 0"
+"l16" 4 "0 -1 0"
+"o16" 4 "0 -1 0"
+"o17" 4 "0 -1 0"
+"n17" 4 "0 -1 0"
+"m17" 4 "0 -1 0"
+"l17" 4 "0 -1 0"
+"k17" 4 "0 -1 0"
+"m16" 4 "0 -1 0"
+"n16" 4 "0 -1 0"
+"k18" 4 "0 -1 0"
+"l18" 4 "0 -1 0"
+"m18" 4 "0 -1 0"
+"n18" 4 "0 -1 0"
+"o18" 4 "0 -1 0"
+"n15" 4 "0 -1 0"
+"a20" 6 "0 -1 0"
+"b19" 6 "0 -1 0"
+"m12" 2 "0 -1 0"
+"m11" 2 "0 -1 0"
+"i14" 3 "0 -1 0"
+"h14" 3 "0 -1 0"
+"h13" 3 "0 -1 0"
+"i17" 4 "0 -1 0"
+"h17" 4 "0 -1 0"
+"g17" 4 "0 -1 0"
--- /dev/null
+// bulldozer storage "level4" last updated 16-11-2015 04:16:07
+nextlevel = "level1"
+"e15" 3 "0 0 0"
+"f14" 3 "0 0 0"
+"g13" 3 "0 0 0"
+"k13" 3 "0 0 0"
+"b14" 4 "0 0 0"
+"a14" 4 "0 0 0"
+"a13" 4 "0 0 0"
+"b13" 4 "0 0 0"
+"i13" 3 "0 0 0"
+"m13" 3 "0 0 0"
+"n14" 3 "0 0 0"
+"o15" 3 "0 0 0"
+"h17" 2 "0 0 0"
+"l17" 2 "0 0 0"
+"c12" 2 "0 0 0"
+"c13" 2 "0 0 0"
+"c14" 2 "0 0 0"
+"r14" 2 "0 0 0"
+"r13" 2 "0 0 0"
+"r12" 2 "0 0 0"
+"j15" 1 "0 -1 0"
+"s13" 4 "0 0 0"
+"t13" 4 "0 0 0"
+"t12" 4 "0 0 0"
+"s12" 4 "0 0 0"
+"b12" 4 "0 0 0"
+"a12" 4 "0 0 0"
+"a11" 4 "0 0 0"
+"b11" 4 "0 0 0"
+"c11" 4 "0 0 0"
+"d11" 4 "0 0 0"
+"e11" 4 "0 0 0"
+"f11" 4 "0 0 0"
+"g11" 4 "0 0 0"
+"h11" 4 "0 0 0"
+"i11" 4 "0 0 0"
+"j11" 4 "0 0 0"
+"k11" 4 "0 0 0"
+"l11" 4 "0 0 0"
+"m11" 4 "0 0 0"
+"n11" 4 "0 0 0"
+"o11" 4 "0 0 0"
+"p11" 4 "0 0 0"
+"q11" 4 "0 0 0"
+"r11" 4 "0 0 0"
+"s11" 4 "0 0 0"
+"t11" 4 "0 0 0"
+"t6" 6 "0 0 0"
+"s10" 4 "0 0 0"
+"r10" 4 "0 0 0"
+"q10" 4 "0 0 0"
+"b10" 6 "0 0 0"
+"o10" 4 "0 0 0"
+"c10" 6 "0 0 0"
+"d10" 6 "0 0 0"
+"e6" 4 "0 0 0"
+"b9" 6 "0 0 0"
+"b8" 6 "0 0 0"
+"c7" 4 "0 0 0"
+"b7" 6 "0 0 0"
+"b6" 6 "0 0 0"
+"c6" 6 "0 0 0"
+"d6" 6 "0 0 0"
+"f10" 6 "0 0 0"
+"g10" 6 "0 0 0"
+"h10" 6 "0 0 0"
+"a10" 4 "0 0 0"
+"a9" 4 "0 0 0"
+"h9" 4 "0 0 0"
+"c9" 4 "0 0 0"
+"d9" 4 "0 0 0"
+"h8" 4 "0 0 0"
+"h7" 4 "0 0 0"
+"i10" 6 "0 0 0"
+"i9" 6 "0 0 0"
+"j7" 4 "0 0 0"
+"j6" 4 "0 0 0"
+"j10" 4 "0 0 0"
+"i8" 6 "0 0 0"
+"m9" 4 "0 0 0"
+"i7" 6 "0 0 0"
+"o9" 4 "0 0 0"
+"i6" 6 "0 0 0"
+"q9" 4 "0 0 0"
+"r9" 4 "0 0 0"
+"s9" 4 "0 0 0"
+"h6" 6 "0 0 0"
+"g6" 6 "0 0 0"
+"s8" 4 "0 0 0"
+"r8" 4 "0 0 0"
+"q8" 4 "0 0 0"
+"f6" 6 "0 0 0"
+"o8" 4 "0 0 0"
+"f7" 6 "0 0 0"
+"m8" 4 "0 0 0"
+"f8" 6 "0 0 0"
+"f9" 6 "0 0 0"
+"k10" 6 "0 0 0"
+"e10" 4 "0 0 0"
+"d7" 4 "0 0 0"
+"e9" 4 "0 0 0"
+"e8" 4 "0 0 0"
+"e7" 4 "0 0 0"
+"l10" 6 "0 0 0"
+"c8" 4 "0 0 0"
+"m10" 6 "0 0 0"
+"a8" 4 "0 0 0"
+"a7" 4 "0 0 0"
+"g7" 4 "0 0 0"
+"g8" 4 "0 0 0"
+"g9" 4 "0 0 0"
+"n10" 6 "0 0 0"
+"n9" 6 "0 0 0"
+"n8" 6 "0 0 0"
+"d8" 4 "0 0 0"
+"n7" 6 "0 0 0"
+"n6" 6 "0 0 0"
+"m6" 6 "0 0 0"
+"l6" 6 "0 0 0"
+"m7" 4 "0 0 0"
+"k6" 6 "0 0 0"
+"o7" 4 "0 0 0"
+"k7" 6 "0 0 0"
+"q7" 4 "0 0 0"
+"r7" 4 "0 0 0"
+"s7" 4 "0 0 0"
+"k8" 6 "0 0 0"
+"k9" 6 "0 0 0"
+"s6" 4 "0 0 0"
+"p9" 6 "0 0 0"
+"p8" 6 "0 0 0"
+"p7" 6 "0 0 0"
+"o6" 4 "0 0 0"
+"p6" 6 "0 0 0"
+"q6" 6 "0 0 0"
+"r6" 6 "0 0 0"
+"p10" 6 "0 0 0"
+"j9" 4 "0 0 0"
+"j8" 4 "0 0 0"
+"t10" 6 "0 0 0"
+"t9" 6 "0 0 0"
+"t8" 6 "0 0 0"
+"l7" 4 "0 0 0"
+"l8" 4 "0 0 0"
+"l9" 4 "0 0 0"
+"t7" 4 "0 0 0"
+"a6" 4 "0 0 0"
+"a5" 4 "0 0 0"
+"b5" 4 "0 0 0"
+"c5" 4 "0 0 0"
+"d5" 4 "0 0 0"
+"e5" 4 "0 0 0"
+"f5" 4 "0 0 0"
+"g5" 4 "0 0 0"
+"h5" 4 "0 0 0"
+"i5" 4 "0 0 0"
+"j5" 4 "0 0 0"
+"k5" 4 "0 0 0"
+"l5" 4 "0 0 0"
+"m5" 4 "0 0 0"
+"n5" 4 "0 0 0"
+"o5" 4 "0 0 0"
+"p5" 4 "0 0 0"
+"q5" 4 "0 0 0"
+"r5" 4 "0 0 0"
+"s5" 4 "0 0 0"
+"t5" 4 "0 0 0"
+"t4" 4 "0 0 0"
+"s4" 4 "0 0 0"
+"r4" 4 "0 0 0"
+"q4" 4 "0 0 0"
+"p4" 4 "0 0 0"
+"o4" 4 "0 0 0"
+"n4" 4 "0 0 0"
+"m4" 4 "0 0 0"
+"l4" 4 "0 0 0"
+"k4" 4 "0 0 0"
+"j4" 4 "0 0 0"
+"i4" 4 "0 0 0"
+"h4" 4 "0 0 0"
+"g4" 4 "0 0 0"
+"f4" 4 "0 0 0"
+"e4" 4 "0 0 0"
+"d4" 4 "0 0 0"
+"c4" 4 "0 0 0"
+"b4" 4 "0 0 0"
+"a4" 4 "0 0 0"
+"a3" 4 "0 0 0"
+"b3" 4 "0 0 0"
+"c3" 4 "0 0 0"
+"d3" 4 "0 0 0"
+"e3" 4 "0 0 0"
+"f3" 4 "0 0 0"
+"g3" 4 "0 0 0"
+"h3" 4 "0 0 0"
+"i3" 4 "0 0 0"
+"j3" 4 "0 0 0"
+"k3" 4 "0 0 0"
+"l3" 4 "0 0 0"
+"m3" 4 "0 0 0"
+"n3" 4 "0 0 0"
+"o3" 4 "0 0 0"
+"p3" 4 "0 0 0"
+"q3" 4 "0 0 0"
+"r3" 4 "0 0 0"
+"s3" 4 "0 0 0"
+"t3" 4 "0 0 0"
+"t2" 4 "0 0 0"
+"s2" 4 "0 0 0"
+"r2" 4 "0 0 0"
+"q2" 4 "0 0 0"
+"p2" 4 "0 0 0"
+"o2" 4 "0 0 0"
+"n2" 4 "0 0 0"
+"m2" 4 "0 0 0"
+"l2" 4 "0 0 0"
+"k2" 4 "0 0 0"
+"j2" 4 "0 0 0"
+"i2" 4 "0 0 0"
+"h2" 4 "0 0 0"
+"g2" 4 "0 0 0"
+"f2" 4 "0 0 0"
+"e2" 4 "0 0 0"
+"d2" 4 "0 0 0"
+"c2" 4 "0 0 0"
+"b2" 4 "0 0 0"
+"a2" 4 "0 0 0"
+"a1" 4 "0 0 0"
+"b1" 4 "0 0 0"
+"c1" 4 "0 0 0"
+"d1" 4 "0 0 0"
+"e1" 4 "0 0 0"
+"f1" 4 "0 0 0"
+"g1" 4 "0 0 0"
+"h1" 4 "0 0 0"
+"i1" 4 "0 0 0"
+"j1" 4 "0 0 0"
+"k1" 4 "0 0 0"
+"l1" 4 "0 0 0"
+"m1" 4 "0 0 0"
+"n1" 4 "0 0 0"
+"o1" 4 "0 0 0"
+"p1" 4 "0 0 0"
+"q1" 4 "0 0 0"
+"r1" 4 "0 0 0"
+"s1" 4 "0 0 0"
+"t1" 4 "0 0 0"
+"t14" 4 "0 0 0"
+"s14" 4 "0 0 0"
+"b15" 4 "0 0 0"
+"a15" 4 "0 0 0"
+"a16" 4 "0 0 0"
+"b16" 4 "0 0 0"
+"s16" 4 "0 0 0"
+"t16" 4 "0 0 0"
+"t15" 4 "0 0 0"
+"s15" 4 "0 0 0"
+"t17" 4 "0 0 0"
+"s17" 4 "0 0 0"
+"b17" 4 "0 0 0"
+"a17" 4 "0 0 0"
+"a18" 4 "0 0 0"
+"b18" 4 "0 0 0"
+"s18" 4 "0 0 0"
+"t18" 4 "0 0 0"
+"t19" 4 "0 0 0"
+"s19" 4 "0 0 0"
+"r19" 4 "0 0 0"
+"q19" 4 "0 0 0"
+"p19" 4 "0 0 0"
+"o19" 4 "0 0 0"
+"n19" 4 "0 0 0"
+"m19" 4 "0 0 0"
+"l19" 4 "0 0 0"
+"k19" 4 "0 0 0"
+"j19" 4 "0 0 0"
+"i19" 4 "0 0 0"
+"h19" 4 "0 0 0"
+"g19" 4 "0 0 0"
+"f19" 4 "0 0 0"
+"e19" 4 "0 0 0"
+"d19" 4 "0 0 0"
+"c19" 4 "0 0 0"
+"b19" 4 "0 0 0"
+"a19" 4 "0 0 0"
+"a20" 4 "0 0 0"
+"b20" 4 "0 0 0"
+"c20" 4 "0 0 0"
+"d20" 4 "0 0 0"
+"e20" 4 "0 0 0"
+"f20" 4 "0 0 0"
+"g20" 4 "0 0 0"
+"h20" 4 "0 0 0"
+"i20" 4 "0 0 0"
+"j20" 4 "0 0 0"
+"k20" 4 "0 0 0"
+"l20" 4 "0 0 0"
+"m20" 4 "0 0 0"
+"n20" 4 "0 0 0"
+"o20" 4 "0 0 0"
+"p20" 4 "0 0 0"
+"q20" 4 "0 0 0"
+"r20" 4 "0 0 0"
+"s20" 4 "0 0 0"
+"t20" 4 "0 0 0"
return ret;
}
+entity announcer_countdown;
+
void Announcer_Countdown()
{
SELFPARAM();
{
Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_ROUNDSTOP);
remove(this);
+ announcer_countdown = NULL;
return;
}
if(roundstarttime >= starttime)
Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN);
Local_Notification(MSG_MULTI, MULTI_COUNTDOWN_BEGIN);
remove(this);
+ announcer_countdown = NULL;
return;
}
else // countdown is still going
{
if(time < startTime)
{
- static entity announcer_countdown;
if (!announcer_countdown)
{
announcer_countdown = new(announcer_countdown);
case "quickmenu":
{
+ if (argv(2) == "help")
+ {
+ LOG_INFO(" quickmenu [[default | file | \"\"] submenu]\n");
+ LOG_INFO("Called without options (or with \"\") loads either the default quickmenu or a quickmenu file if hud_panel_quickmenu_file is set to a valid filename.\n");
+ LOG_INFO("A submenu name can be given to open the quickmenu directly in a submenu; it requires to specify 'default', 'file' or '\"\"' option.\n");
+ return;
+ }
if (QuickMenu_IsOpened())
QuickMenu_Close();
else
LOG_INFO(" 'configname' is the name to save to for \"save\" action,\n");
LOG_INFO(" 'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action,\n");
LOG_INFO(" and 'layout' is how to organize the scoreboard columns for the set action.\n");
- LOG_INFO(" quickmenu [[default | file | \"\"] submenu]\n");
- LOG_INFO(" Called without options (or with " ") loads either the default quickmenu or a quickmenu file if hud_panel_quickmenu_file is set to a valid filename.\n");
- LOG_INFO(" Submenu option allows to open quickmenu directly in a submenu, it requires to specify 'default', 'file' or '\"\"' option.\n");
- LOG_INFO(" Full list of commands here: \"configure, minigame, save, scoreboard_columns_help, scoreboard_columns_set, radar.\"\n");
+ LOG_INFO(" Full list of commands here: \"configure, quickmenu, minigame, save, scoreboard_columns_help, scoreboard_columns_set, radar.\"\n");
return;
}
}
// only if this failed, find it out on our own
entity e = spawn();
+ precache_model(autocvar__cl_playermodel);
_setmodel(e, autocvar__cl_playermodel); // this is harmless, see below
forceplayermodels_modelisgoodmodel = fexists(e.model);
forceplayermodels_model = e.model;
}
void CSQCPlayer_AnimDecide_PostUpdate(bool isnew)
{SELFPARAM();
- self.csqcmodel_isdead = !!(self.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2));
+ self.csqcmodel_isdead = boolean(self.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2));
}
int CSQCPlayer_FallbackFrame(int f)
{SELFPARAM();
self.teleport_time = 0;
}
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(this);
int s = W_GetGunAlignment(world);
self.HookSilent = (sf & 0x80);
self.iflags = IFLAG_VELOCITY | IFLAG_ORIGIN;
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
if(sf & 1)
{
self.velocity_z = ReadCoord();
}
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
if(bIsNew || !self.teleport_time)
{
#include "scoreboard.qh"
#include "teamradar.qh"
#include "t_items.qh"
-#include "../common/buffs/all.qh"
#include "../common/deathtypes/all.qh"
#include "../common/items/all.qc"
#include "../common/mapinfo.qh"
#include "../common/mutators/mutator/waypoints/all.qh"
-#include "../common/nades/all.qh"
#include "../common/stats.qh"
#include "../lib/csqcmodel/cl_player.qh"
// TODO: remove
REGISTRY(hud_panels, BITS(6))
#define hud_panels_from(i) _hud_panels_from(i, NULL)
-REGISTER_REGISTRY(Registerhud_panels)
+REGISTER_REGISTRY(hud_panels)
#define REGISTER_HUD_PANEL(id, draw_func, name, configflags, showflags) \
void draw_func(); \
- REGISTER(Registerhud_panels, HUD_PANEL, hud_panels, id, m_id, new(hud_panel)) { \
+ REGISTER(hud_panels, HUD_PANEL, id, m_id, new(hud_panel)) { \
make_pure(this); \
this.panel_id = this.m_id; \
this.panel_draw = draw_func; \
#include "hud.qh"
#define HUD_Write(s) fputs(fh, s)
-// q: quoted, n: not quoted
-#define HUD_Write_Cvar_n(cvar) HUD_Write(strcat("seta ", cvar, " ", cvar_string(cvar), "\n"))
-#define HUD_Write_Cvar_q(cvar) HUD_Write(strcat("seta ", cvar, " \"", cvar_string(cvar), "\"\n"))
-#define HUD_Write_PanelCvar_n(cvar_suf) HUD_Write_Cvar_n(strcat("hud_panel_", panel.panel_name, cvar_suf))
-#define HUD_Write_PanelCvar_q(cvar_suf) HUD_Write_Cvar_q(strcat("hud_panel_", panel.panel_name, cvar_suf))
+#define HUD_Write_Cvar(cvar) HUD_Write(strcat("seta ", cvar, " \"", cvar_string(cvar), "\"\n"))
+#define HUD_Write_PanelCvar(cvar_suf) HUD_Write_Cvar(strcat("hud_panel_", panel.panel_name, cvar_suf))
// Save the config
void HUD_Panel_ExportCfg(string cfgname)
{
fh = fopen(filename, FILE_WRITE);
if(fh >= 0)
{
- HUD_Write_Cvar_q("hud_skin");
- HUD_Write_Cvar_q("hud_panel_bg");
- HUD_Write_Cvar_q("hud_panel_bg_color");
- HUD_Write_Cvar_q("hud_panel_bg_color_team");
- HUD_Write_Cvar_q("hud_panel_bg_alpha");
- HUD_Write_Cvar_q("hud_panel_bg_border");
- HUD_Write_Cvar_q("hud_panel_bg_padding");
- HUD_Write_Cvar_q("hud_panel_fg_alpha");
+ HUD_Write_Cvar("hud_skin");
+ HUD_Write_Cvar("hud_panel_bg");
+ HUD_Write_Cvar("hud_panel_bg_color");
+ HUD_Write_Cvar("hud_panel_bg_color_team");
+ HUD_Write_Cvar("hud_panel_bg_alpha");
+ HUD_Write_Cvar("hud_panel_bg_border");
+ HUD_Write_Cvar("hud_panel_bg_padding");
+ HUD_Write_Cvar("hud_panel_fg_alpha");
HUD_Write("\n");
- HUD_Write_Cvar_q("hud_dock");
- HUD_Write_Cvar_q("hud_dock_color");
- HUD_Write_Cvar_q("hud_dock_color_team");
- HUD_Write_Cvar_q("hud_dock_alpha");
+ HUD_Write_Cvar("hud_dock");
+ HUD_Write_Cvar("hud_dock_color");
+ HUD_Write_Cvar("hud_dock_color_team");
+ HUD_Write_Cvar("hud_dock_alpha");
HUD_Write("\n");
- HUD_Write_Cvar_q("hud_progressbar_alpha");
- HUD_Write_Cvar_q("hud_progressbar_strength_color");
- HUD_Write_Cvar_q("hud_progressbar_shield_color");
- HUD_Write_Cvar_q("hud_progressbar_health_color");
- HUD_Write_Cvar_q("hud_progressbar_armor_color");
- HUD_Write_Cvar_q("hud_progressbar_fuel_color");
- HUD_Write_Cvar_q("hud_progressbar_nexball_color");
- HUD_Write_Cvar_q("hud_progressbar_speed_color");
- HUD_Write_Cvar_q("hud_progressbar_acceleration_color");
- HUD_Write_Cvar_q("hud_progressbar_acceleration_neg_color");
+ HUD_Write_Cvar("hud_progressbar_alpha");
+ HUD_Write_Cvar("hud_progressbar_strength_color");
+ HUD_Write_Cvar("hud_progressbar_superweapons_color");
+ HUD_Write_Cvar("hud_progressbar_shield_color");
+ HUD_Write_Cvar("hud_progressbar_health_color");
+ HUD_Write_Cvar("hud_progressbar_armor_color");
+ HUD_Write_Cvar("hud_progressbar_fuel_color");
+ HUD_Write_Cvar("hud_progressbar_nexball_color");
+ HUD_Write_Cvar("hud_progressbar_speed_color");
+ HUD_Write_Cvar("hud_progressbar_acceleration_color");
+ HUD_Write_Cvar("hud_progressbar_acceleration_neg_color");
+ HUD_Write_Cvar("hud_progressbar_vehicles_ammo1_color");
+ HUD_Write_Cvar("hud_progressbar_vehicles_ammo2_color");
HUD_Write("\n");
- HUD_Write_Cvar_q("_hud_panelorder");
+ HUD_Write_Cvar("_hud_panelorder");
HUD_Write("\n");
- HUD_Write_Cvar_q("hud_configure_grid");
- HUD_Write_Cvar_q("hud_configure_grid_xsize");
- HUD_Write_Cvar_q("hud_configure_grid_ysize");
+ HUD_Write_Cvar("hud_configure_grid");
+ HUD_Write_Cvar("hud_configure_grid_xsize");
+ HUD_Write_Cvar("hud_configure_grid_ysize");
HUD_Write("\n");
// common cvars for all panels
{
panel = hud_panels_from(i);
- HUD_Write_PanelCvar_n("");
- HUD_Write_PanelCvar_q("_pos");
- HUD_Write_PanelCvar_q("_size");
- HUD_Write_PanelCvar_q("_bg");
- HUD_Write_PanelCvar_q("_bg_color");
- HUD_Write_PanelCvar_q("_bg_color_team");
- HUD_Write_PanelCvar_q("_bg_alpha");
- HUD_Write_PanelCvar_q("_bg_border");
- HUD_Write_PanelCvar_q("_bg_padding");
+ HUD_Write_PanelCvar("");
+ HUD_Write_PanelCvar("_pos");
+ HUD_Write_PanelCvar("_size");
+ HUD_Write_PanelCvar("_bg");
+ HUD_Write_PanelCvar("_bg_color");
+ HUD_Write_PanelCvar("_bg_color_team");
+ HUD_Write_PanelCvar("_bg_alpha");
+ HUD_Write_PanelCvar("_bg_border");
+ HUD_Write_PanelCvar("_bg_padding");
switch(panel) {
case HUD_PANEL_WEAPONS:
- HUD_Write_PanelCvar_q("_accuracy");
- HUD_Write_PanelCvar_q("_label");
- HUD_Write_PanelCvar_q("_label_scale");
- HUD_Write_PanelCvar_q("_complainbubble");
- HUD_Write_PanelCvar_q("_complainbubble_padding");
- HUD_Write_PanelCvar_q("_complainbubble_time");
- HUD_Write_PanelCvar_q("_complainbubble_fadetime");
- HUD_Write_PanelCvar_q("_complainbubble_color_outofammo");
- HUD_Write_PanelCvar_q("_complainbubble_color_donthave");
- HUD_Write_PanelCvar_q("_complainbubble_color_unavailable");
- HUD_Write_PanelCvar_q("_ammo");
- HUD_Write_PanelCvar_q("_ammo_color");
- HUD_Write_PanelCvar_q("_ammo_alpha");
- HUD_Write_PanelCvar_q("_aspect");
- HUD_Write_PanelCvar_q("_timeout");
- HUD_Write_PanelCvar_q("_timeout_effect");
- HUD_Write_PanelCvar_q("_timeout_fadebgmin");
- HUD_Write_PanelCvar_q("_timeout_fadefgmin");
- HUD_Write_PanelCvar_q("_timeout_speed_in");
- HUD_Write_PanelCvar_q("_timeout_speed_out");
- HUD_Write_PanelCvar_q("_onlyowned");
- HUD_Write_PanelCvar_q("_noncurrent_alpha");
- HUD_Write_PanelCvar_q("_noncurrent_scale");
+ HUD_Write_PanelCvar("_accuracy");
+ HUD_Write_PanelCvar("_label");
+ HUD_Write_PanelCvar("_label_scale");
+ HUD_Write_PanelCvar("_complainbubble");
+ HUD_Write_PanelCvar("_complainbubble_padding");
+ HUD_Write_PanelCvar("_complainbubble_time");
+ HUD_Write_PanelCvar("_complainbubble_fadetime");
+ HUD_Write_PanelCvar("_complainbubble_color_outofammo");
+ HUD_Write_PanelCvar("_complainbubble_color_donthave");
+ HUD_Write_PanelCvar("_complainbubble_color_unavailable");
+ HUD_Write_PanelCvar("_ammo");
+ HUD_Write_PanelCvar("_ammo_color");
+ HUD_Write_PanelCvar("_ammo_alpha");
+ HUD_Write_PanelCvar("_aspect");
+ HUD_Write_PanelCvar("_timeout");
+ HUD_Write_PanelCvar("_timeout_effect");
+ HUD_Write_PanelCvar("_timeout_fadebgmin");
+ HUD_Write_PanelCvar("_timeout_fadefgmin");
+ HUD_Write_PanelCvar("_timeout_speed_in");
+ HUD_Write_PanelCvar("_timeout_speed_out");
+ HUD_Write_PanelCvar("_onlyowned");
+ HUD_Write_PanelCvar("_noncurrent_alpha");
+ HUD_Write_PanelCvar("_noncurrent_scale");
break;
case HUD_PANEL_AMMO:
- HUD_Write_PanelCvar_q("_onlycurrent");
- HUD_Write_PanelCvar_q("_noncurrent_alpha");
- HUD_Write_PanelCvar_q("_noncurrent_scale");
- HUD_Write_PanelCvar_q("_iconalign");
- HUD_Write_PanelCvar_q("_progressbar");
- HUD_Write_PanelCvar_q("_progressbar_name");
- HUD_Write_PanelCvar_q("_progressbar_xoffset");
- HUD_Write_PanelCvar_q("_text");
+ HUD_Write_PanelCvar("_onlycurrent");
+ HUD_Write_PanelCvar("_noncurrent_alpha");
+ HUD_Write_PanelCvar("_noncurrent_scale");
+ HUD_Write_PanelCvar("_iconalign");
+ HUD_Write_PanelCvar("_progressbar");
+ HUD_Write_PanelCvar("_progressbar_name");
+ HUD_Write_PanelCvar("_progressbar_xoffset");
+ HUD_Write_PanelCvar("_text");
break;
case HUD_PANEL_POWERUPS:
- HUD_Write_PanelCvar_q("_iconalign");
- HUD_Write_PanelCvar_q("_baralign");
- HUD_Write_PanelCvar_q("_progressbar");
- HUD_Write_PanelCvar_q("_text");
+ HUD_Write_PanelCvar("_iconalign");
+ HUD_Write_PanelCvar("_baralign");
+ HUD_Write_PanelCvar("_progressbar");
+ HUD_Write_PanelCvar("_text");
break;
case HUD_PANEL_HEALTHARMOR:
- HUD_Write_PanelCvar_q("_flip");
- HUD_Write_PanelCvar_q("_iconalign");
- HUD_Write_PanelCvar_q("_baralign");
- HUD_Write_PanelCvar_q("_progressbar");
- HUD_Write_PanelCvar_q("_progressbar_health");
- HUD_Write_PanelCvar_q("_progressbar_armor");
- HUD_Write_PanelCvar_q("_progressbar_gfx");
- HUD_Write_PanelCvar_q("_progressbar_gfx_smooth");
- HUD_Write_PanelCvar_q("_text");
+ HUD_Write_PanelCvar("_flip");
+ HUD_Write_PanelCvar("_iconalign");
+ HUD_Write_PanelCvar("_baralign");
+ HUD_Write_PanelCvar("_progressbar");
+ HUD_Write_PanelCvar("_progressbar_health");
+ HUD_Write_PanelCvar("_progressbar_armor");
+ HUD_Write_PanelCvar("_progressbar_gfx");
+ HUD_Write_PanelCvar("_progressbar_gfx_smooth");
+ HUD_Write_PanelCvar("_text");
break;
case HUD_PANEL_NOTIFY:
- HUD_Write_PanelCvar_q("_flip");
- HUD_Write_PanelCvar_q("_fontsize");
- HUD_Write_PanelCvar_q("_time");
- HUD_Write_PanelCvar_q("_fadetime");
- HUD_Write_PanelCvar_q("_icon_aspect");
+ HUD_Write_PanelCvar("_flip");
+ HUD_Write_PanelCvar("_fontsize");
+ HUD_Write_PanelCvar("_time");
+ HUD_Write_PanelCvar("_fadetime");
+ HUD_Write_PanelCvar("_icon_aspect");
break;
case HUD_PANEL_TIMER:
- HUD_Write_PanelCvar_q("_increment");
break;
case HUD_PANEL_RADAR:
- HUD_Write_PanelCvar_q("_foreground_alpha");
- HUD_Write_PanelCvar_q("_rotation");
- HUD_Write_PanelCvar_q("_zoommode");
- HUD_Write_PanelCvar_q("_scale");
- HUD_Write_PanelCvar_q("_maximized_scale");
- HUD_Write_PanelCvar_q("_maximized_size");
- HUD_Write_PanelCvar_q("_maximized_rotation");
- HUD_Write_PanelCvar_q("_maximized_zoommode");
+ HUD_Write_PanelCvar("_foreground_alpha");
+ HUD_Write_PanelCvar("_rotation");
+ HUD_Write_PanelCvar("_zoommode");
+ HUD_Write_PanelCvar("_scale");
+ HUD_Write_PanelCvar("_maximized_scale");
+ HUD_Write_PanelCvar("_maximized_size");
+ HUD_Write_PanelCvar("_maximized_rotation");
+ HUD_Write_PanelCvar("_maximized_zoommode");
break;
case HUD_PANEL_SCORE:
- HUD_Write_PanelCvar_q("_rankings");
+ HUD_Write_PanelCvar("_rankings");
break;
case HUD_PANEL_VOTE:
- HUD_Write_PanelCvar_q("_alreadyvoted_alpha");
+ HUD_Write_PanelCvar("_alreadyvoted_alpha");
break;
case HUD_PANEL_MODICONS:
- HUD_Write_PanelCvar_q("_ca_layout");
- HUD_Write_PanelCvar_q("_dom_layout");
- HUD_Write_PanelCvar_q("_freezetag_layout");
+ HUD_Write_PanelCvar("_ca_layout");
+ HUD_Write_PanelCvar("_dom_layout");
+ HUD_Write_PanelCvar("_freezetag_layout");
break;
case HUD_PANEL_PRESSEDKEYS:
- HUD_Write_PanelCvar_q("_aspect");
- HUD_Write_PanelCvar_q("_attack");
+ HUD_Write_PanelCvar("_aspect");
+ HUD_Write_PanelCvar("_attack");
break;
case HUD_PANEL_ENGINEINFO:
- HUD_Write_PanelCvar_q("_framecounter_time");
- HUD_Write_PanelCvar_q("_framecounter_decimals");
+ HUD_Write_PanelCvar("_framecounter_time");
+ HUD_Write_PanelCvar("_framecounter_decimals");
break;
case HUD_PANEL_INFOMESSAGES:
- HUD_Write_PanelCvar_q("_flip");
+ HUD_Write_PanelCvar("_flip");
break;
case HUD_PANEL_PHYSICS:
- HUD_Write_PanelCvar_q("_speed_unit");
- HUD_Write_PanelCvar_q("_speed_unit_show");
- HUD_Write_PanelCvar_q("_speed_max");
- HUD_Write_PanelCvar_q("_speed_vertical");
- HUD_Write_PanelCvar_q("_topspeed");
- HUD_Write_PanelCvar_q("_topspeed_time");
- HUD_Write_PanelCvar_q("_acceleration_max");
- HUD_Write_PanelCvar_q("_acceleration_vertical");
- HUD_Write_PanelCvar_q("_flip");
- HUD_Write_PanelCvar_q("_baralign");
- HUD_Write_PanelCvar_q("_progressbar");
- HUD_Write_PanelCvar_q("_progressbar_acceleration_mode");
- HUD_Write_PanelCvar_q("_progressbar_acceleration_scale");
- HUD_Write_PanelCvar_q("_progressbar_acceleration_nonlinear");
- HUD_Write_PanelCvar_q("_text");
- HUD_Write_PanelCvar_q("_text_scale");
+ HUD_Write_PanelCvar("_speed_unit_show");
+ HUD_Write_PanelCvar("_speed_max");
+ HUD_Write_PanelCvar("_speed_vertical");
+ HUD_Write_PanelCvar("_topspeed");
+ HUD_Write_PanelCvar("_topspeed_time");
+ HUD_Write_PanelCvar("_acceleration_max");
+ HUD_Write_PanelCvar("_acceleration_vertical");
+ HUD_Write_PanelCvar("_flip");
+ HUD_Write_PanelCvar("_baralign");
+ HUD_Write_PanelCvar("_progressbar");
+ HUD_Write_PanelCvar("_acceleration_progressbar_mode");
+ HUD_Write_PanelCvar("_acceleration_progressbar_scale");
+ HUD_Write_PanelCvar("_acceleration_progressbar_nonlinear");
+ HUD_Write_PanelCvar("_text");
+ HUD_Write_PanelCvar("_text_scale");
break;
case HUD_PANEL_CENTERPRINT:
- HUD_Write_PanelCvar_q("_align");
- HUD_Write_PanelCvar_q("_flip");
- HUD_Write_PanelCvar_q("_fontscale");
- HUD_Write_PanelCvar_q("_time");
- HUD_Write_PanelCvar_q("_fade_in");
- HUD_Write_PanelCvar_q("_fade_out");
- HUD_Write_PanelCvar_q("_fade_subsequent");
- HUD_Write_PanelCvar_q("_fade_subsequent_passone");
- HUD_Write_PanelCvar_q("_fade_subsequent_passone_minalpha");
- HUD_Write_PanelCvar_q("_fade_subsequent_passtwo");
- HUD_Write_PanelCvar_q("_fade_subsequent_passtwo_minalpha");
- HUD_Write_PanelCvar_q("_fade_subsequent_minfontsize");
- HUD_Write_PanelCvar_q("_fade_minfontsize");
+ HUD_Write_PanelCvar("_align");
+ HUD_Write_PanelCvar("_flip");
+ HUD_Write_PanelCvar("_fontscale");
+ HUD_Write_PanelCvar("_time");
+ HUD_Write_PanelCvar("_fade_in");
+ HUD_Write_PanelCvar("_fade_out");
+ HUD_Write_PanelCvar("_fade_subsequent");
+ HUD_Write_PanelCvar("_fade_subsequent_passone");
+ HUD_Write_PanelCvar("_fade_subsequent_passone_minalpha");
+ HUD_Write_PanelCvar("_fade_subsequent_passtwo");
+ HUD_Write_PanelCvar("_fade_subsequent_passtwo_minalpha");
+ HUD_Write_PanelCvar("_fade_subsequent_minfontsize");
+ HUD_Write_PanelCvar("_fade_minfontsize");
break;
case HUD_PANEL_ITEMSTIME:
- HUD_Write_PanelCvar_q("_iconalign");
- HUD_Write_PanelCvar_q("_progressbar");
- HUD_Write_PanelCvar_q("_progressbar_name");
- HUD_Write_PanelCvar_q("_progressbar_reduced");
- HUD_Write_PanelCvar_q("_text");
- HUD_Write_PanelCvar_q("_ratio");
- HUD_Write_PanelCvar_q("_dynamicsize");
+ HUD_Write_PanelCvar("_iconalign");
+ HUD_Write_PanelCvar("_progressbar");
+ HUD_Write_PanelCvar("_progressbar_name");
+ HUD_Write_PanelCvar("_progressbar_reduced");
+ HUD_Write_PanelCvar("_text");
+ HUD_Write_PanelCvar("_ratio");
+ HUD_Write_PanelCvar("_dynamicsize");
+ break;
case HUD_PANEL_QUICKMENU:
- HUD_Write_PanelCvar_q("_align");
+ HUD_Write_PanelCvar("_align");
break;
}
HUD_Write("\n");
autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
}
-void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time)
-{
- float bonusNades = STAT(NADE_BONUS);
- float bonusProgress = STAT(NADE_BONUS_SCORE);
- float bonusType = STAT(NADE_BONUS_TYPE);
- Nade def = Nades_from(bonusType);
- vector nadeColor = def.m_color;
- string nadeIcon = def.m_icon;
-
- vector iconPos, textPos;
-
- if(autocvar_hud_panel_ammo_iconalign)
- {
- iconPos = myPos + eX * 2 * mySize.y;
- textPos = myPos;
- }
- else
- {
- iconPos = myPos;
- textPos = myPos + eX * mySize.y;
- }
-
- if(bonusNades > 0 || bonusProgress > 0)
- {
- DrawNadeProgressBar(myPos, mySize, bonusProgress, nadeColor);
-
- if(autocvar_hud_panel_ammo_text)
- drawstring_aspect(textPos, ftos(bonusNades), eX * (2/3) * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-
- if(draw_expanding)
- drawpic_aspect_skin_expanding(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, expand_time);
-
- drawpic_aspect_skin(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- }
-}
+void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time); // TODO: mutator
void DrawAmmoItem(vector myPos, vector mySize, .int ammoType, bool isCurrent, bool isInfinite)
{
if(superTime)
addPowerupItem("Superweapons", "superweapons", autocvar_hud_progressbar_superweapons_color, superTime, 30);
- FOREACH(Buffs, it.m_itemid & allBuffs, LAMBDA(
- addPowerupItem(it.m_prettyName, strcat("buff_", it.m_name), it.m_color, bound(0, STAT(BUFF_TIME) - time, 99), 60);
- ));
+ MUTATOR_CALLHOOK(HUD_Powerups_add);
if(!powerupItemsCount)
return;
if((hud_panel_radar_rotation == 0 && !hud_panel_radar_maximized) || (hud_panel_radar_maximized_rotation == 0 && hud_panel_radar_maximized))
{
// max-min distance must fit the radar in any rotation
- bigsize = vlen_minnorm2d(teamradar_size2d) * scale2d / (1.05 * vlen2d(mi_scale));
+ bigsize = vlen_minnorm2d(teamradar_size2d) * scale2d / (1.05 * vlen(vec2(mi_scale)));
}
else
{
}
for(tm = world; (tm = find(tm, classname, "entcs_receiver")); )
{
+ if (!tm.m_entcs_private) continue;
+ if (entcs_is_self(tm)) continue;
color2 = GetPlayerColor(tm.sv_entnum);
//if(color == NUM_SPECTATOR || color == color2)
draw_teamradar_player(tm.origin, tm.angles, Team_ColorRGB(color2));
int nHidden = 0;
WepSet weapons_stat = WepSet_GetFromStat();
for (int i = WEP_FIRST; i <= WEP_LAST; ++i) {
- WepSet weapons_wep = WepSet_FromWeapon(i);
- if (weapons_stat & weapons_wep) continue;
Weapon w = get_weaponinfo(i);
+ if (weapons_stat & w.m_wepset) continue;
if (w.spawnflags & WEP_FLAG_MUTATORBLOCKED) nHidden += 1;
}
vector table_size = HUD_GetTableSize_BestItemAR((Weapons_COUNT - 1) - nHidden, padded_panel_size, aspect);
prvm_language = strzone(cvar_string("prvm_language"));
#ifdef WATERMARK
- LOG_TRACEF("^4CSQC Build information: ^1%s\n", WATERMARK);
+ LOG_INFOF("^4CSQC Build information: ^1%s\n", WATERMARK);
#endif
binddb = db_create();
// --------------------------------------------------------------------------
// BEGIN OPTIONAL CSQC FUNCTIONS
-void Ent_RemoveEntCS()
-{
- SELFPARAM();
- entcs_receiver[this.sv_entnum] = NULL;
-}
-
-NET_HANDLE(ENT_CLIENT_ENTCS, bool isnew)
-{
- make_pure(this);
- this.classname = "entcs_receiver";
- InterpolateOrigin_Undo();
- int sf = ReadByte();
-
- if(sf & BIT(0))
- this.sv_entnum = ReadByte();
- if (sf & BIT(1))
- {
- this.origin_x = ReadShort();
- this.origin_y = ReadShort();
- this.origin_z = ReadShort();
- setorigin(this, this.origin);
- }
- if (sf & BIT(2))
- {
- this.angles_y = ReadByte() * 360.0 / 256;
- this.angles_x = this.angles_z = 0;
- }
- if (sf & BIT(3))
- this.healthvalue = ReadByte() * 10;
- if (sf & BIT(4))
- this.armorvalue = ReadByte() * 10;
-
- return = true;
-
- entcs_receiver[this.sv_entnum] = this;
- this.entremove = Ent_RemoveEntCS;
- this.iflags |= IFLAG_ORIGIN;
-
- InterpolateOrigin_Note();
-}
-
void Ent_Remove();
void Ent_RemovePlayerScore()
// CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
// The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
-void CSQC_Ent_Update(float bIsNewEntity)
+void CSQC_Ent_Update(bool isnew)
{
SELFPARAM();
this.sourceLocLine = __LINE__;
}
#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
- if(this.enttype)
+ if (this.enttype)
{
- if(t != this.enttype || bIsNewEntity)
+ if (t != this.enttype || isnew)
{
LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(this), this.entnum, this.enttype, t);
Ent_Remove();
clearentity(this);
- bIsNewEntity = 1;
+ isnew = true;
}
}
else
{
- if(!bIsNewEntity)
+ if (!isnew)
{
LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(this), this.entnum, t);
- bIsNewEntity = 1;
+ isnew = true;
}
}
#endif
this.enttype = t;
bool done = false;
FOREACH(LinkedEntities, it.m_id == t, LAMBDA(
- this.classname = it.netname;
+ if (isnew) this.classname = it.netname;
if (autocvar_developer_csqcentities)
- LOG_INFOF("CSQC_Ent_Update(%d) with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", bIsNewEntity, this, this.entnum, this.enttype, it.netname, t);
- done = it.m_read(this, bIsNewEntity);
+ LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
+ done = it.m_read(this, isnew);
break;
));
time = savetime;
if (!done)
{
- //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), this.enttype));
- error(sprintf("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n", this.enttype, num_for_edict(this), this.classname));
+ LOG_FATALF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
}
}
float drawframetime;
vector view_origin, view_forward, view_right, view_up;
-float button_zoom;
-float spectatorbutton_zoom;
-float button_attack2;
+bool button_zoom;
+bool spectatorbutton_zoom;
+bool button_attack2;
int activeweapon;
int switchingweapon;
float g_balance_electro_secondary_bouncestop;
float g_trueaim_minrange;
-entity entcs_receiver[255]; // 255 is the engine limit on maxclients
-
float hud;
float view_quality;
int framecount;
}
}
-vector getplayerorigin(int pl)
+// TODO: entcs
+float getplayeralpha(int pl)
{
- entity e;
-
- e = CSQCModel_server2csqc(pl + 1);
- if(e)
- return e.origin;
-
- e = entcs_receiver[pl];
- if(e)
- return e.origin;
-
- return GETPLAYERORIGIN_ERROR;
-}
-
-float getplayeralpha(float pl)
-{
- entity e;
-
- e = CSQCModel_server2csqc(pl + 1);
- if(e)
- return e.alpha;
-
- return 1;
+ entity e = CSQCModel_server2csqc(pl + 1);
+ return (e) ? e.alpha : 1;
}
-vector getcsqcplayercolor(float pl)
+// TODO: entcs
+vector getcsqcplayercolor(int pl)
{
- entity e;
-
- e = CSQCModel_server2csqc(pl);
- if(e)
- {
- if(e.colormap > 0)
- return colormapPaletteColor(((e.colormap >= 1024) ? e.colormap : stof(getplayerkeyvalue(e.colormap - 1, "colors"))) & 0x0F, true);
- }
-
- return '1 1 1';
+ entity e = CSQCModel_server2csqc(pl);
+ return (e && e.colormap > 0) ? colormapPaletteColor(((e.colormap >= 1024) ? e.colormap : stof(getplayerkeyvalue(e.colormap - 1, "colors"))) & 0x0F, true) : '1 1 1';
}
-float getplayerisdead(float pl)
+// TODO: entcs
+bool getplayerisdead(int pl)
{
- entity e;
-
- e = CSQCModel_server2csqc(pl + 1);
- if(e)
- return e.csqcmodel_isdead;
-
- return false;
+ entity e = CSQCModel_server2csqc(pl + 1);
+ return e ? e.csqcmodel_isdead : false;
}
/** engine callback */
void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector rgb, float a, float drawflag);
-const vector GETPLAYERORIGIN_ERROR = '1123581321 2357111317 3141592653'; // way out of bounds for anything on the map
-vector getplayerorigin(int pl);
-
float getplayeralpha(float pl);
vector getcsqcplayercolor(float pl);
MUTATOR_HOOKABLE(AnnouncerOption, EV_AnnouncerOption);
MUTATOR_HOOKABLE(Ent_Init, EV_NO_ARGS);
+
+#define EV_HUD_Draw_overlay(i, o) \
+ /**/ o(vector, MUTATOR_ARGV_0_vector) \
+ /**/ o(float, MUTATOR_ARGV_0_float) \
+ /**/
+MUTATOR_HOOKABLE(HUD_Draw_overlay, EV_HUD_Draw_overlay);
+
+MUTATOR_HOOKABLE(HUD_Powerups_add, EV_NO_ARGS);
+
+/** Return true to not draw any vortex beam */
+#define EV_Particles_VortexBeam(i, o) \
+ /**/ i(vector, vbeam_shotorg) \
+ /**/ i(vector, vbeam_endpos) \
+ /**/
+vector vbeam_shotorg;
+vector vbeam_endpos;
+MUTATOR_HOOKABLE(Particles_VortexBeam, EV_Particles_VortexBeam);
+
+/** Return true to not draw any impact effect */
+#define EV_Weapon_ImpactEffect(i, o) \
+ /**/ i(entity, w_hitwep) \
+ /**/
+entity w_hitwep;
+MUTATOR_HOOKABLE(Weapon_ImpactEffect, EV_Weapon_ImpactEffect);
+
#endif
#include "../common/animdecide.qc"
#include "../common/effects/effectinfo.qc"
+#include "../common/ent_cs.qc"
#include "../common/mapinfo.qc"
#include "../common/movetypes/include.qc"
#include "../common/net_notice.qc"
#include "../common/minigames/minigames.qc"
#include "../common/minigames/cl_minigames.qc"
-#include "../common/buffs/all.qc"
#include "../common/deathtypes/all.qc"
#include "../common/effects/all.qc"
#include "../common/gamemodes/all.qc"
#include "../common/items/all.qc"
#include "../common/monsters/all.qc"
#include "../common/mutators/all.qc"
-#include "../common/nades/all.qc"
#include "../common/turrets/all.qc"
#include "../common/vehicles/all.qc"
#include "../common/weapons/all.qc"
float initial_posx = pos.x;
int disownedcnt = 0;
for (int i = WEP_FIRST; i <= WEP_LAST; ++i) {
- setself(get_weaponinfo(i));
+ Weapon e = get_weaponinfo(i);
+ setself(e);
if (!self.weapon) continue;
int weapon_stats = weapon_accuracy[i - WEP_FIRST];
- if (weapon_stats < 0 && !(weapons_stat & WepSet_FromWeapon(i) || weapons_inmap & WepSet_FromWeapon(i)))
+ WepSet set = e.m_wepset;
+ if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set))
++disownedcnt;
}
int column = 0;
for (int i = WEP_FIRST; i <= WEP_LAST; ++i) {
- setself(get_weaponinfo(i));
+ Weapon e = get_weaponinfo(i);
+ setself(e);
if (!self.weapon) continue;
int weapon_stats = weapon_accuracy[i - WEP_FIRST];
- if (weapon_stats < 0 && !(weapons_stat & WepSet_FromWeapon(i) || weapons_inmap & WepSet_FromWeapon(i)))
+ WepSet set = e.m_wepset;
+ if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set))
continue;
float weapon_alpha;
#include "../lib/csqcmodel/cl_model.qh"
// self.isactive = player is in range and coordinates/status (health and armor) are up to date
-// self.origin = player origin TODO: should maybe move this so it's the origin of the shownames tag already in SSQC for culling?
+// self.origin = player origin
// self.healthvalue
// self.armorvalue
// self.sameteam = player is on same team as local client
const float SHOWNAMES_FADESPEED = 4;
const float SHOWNAMES_FADEDELAY = 0.4;
-void Draw_ShowNames(entity ent)
+void Draw_ShowNames(entity this)
{
- if(!autocvar_hud_shownames)
- return;
-
- if(ent.sv_entnum == player_localentnum) // ent is me or person i'm spectating
- if(!(autocvar_hud_shownames_self && autocvar_chase_active))
- return;
-
- if(ent.sameteam || (!ent.sameteam && autocvar_hud_shownames_enemies))
+ if (this.sv_entnum == player_localentnum) // self or spectatee
+ if (!(autocvar_hud_shownames_self && autocvar_chase_active)) return;
+ if (!this.sameteam && !autocvar_hud_shownames_enemies) return;
+ bool hit;
+ if (!autocvar_hud_shownames_crosshairdistance && this.sameteam)
{
- ent.origin_z += autocvar_hud_shownames_offset;
-
- float hit;
- if(ent.sameteam && !autocvar_hud_shownames_crosshairdistance)
- {
- hit = 1;
- }
- else
- {
- traceline(view_origin, ent.origin, MOVE_NORMAL, ent);
- if(trace_fraction < 1 && (trace_networkentity != ent.sv_entnum && trace_ent.entnum != ent.sv_entnum))
- hit = 0;
- else
- hit = 1;
- }
-
- // handle tag fading
- float overlap = false, onscreen, crosshairdistance;
- vector o, eo;
-
- o = project_3d_to_2d(ent.origin);
-
- if(autocvar_hud_shownames_antioverlap)
+ hit = true;
+ }
+ else
+ {
+ traceline(view_origin, this.origin, MOVE_NORMAL, this);
+ hit = !(trace_fraction < 1 && (trace_networkentity != this.sv_entnum && trace_ent.entnum != this.sv_entnum));
+ }
+ // handle tag fading
+ bool overlap = false;
+ vector o = project_3d_to_2d(this.origin + eZ * autocvar_hud_shownames_offset);
+ float dist = vlen(this.origin - view_origin);
+ if (autocvar_hud_shownames_antioverlap)
+ {
+ // fade tag out if another tag that is closer to you overlaps
+ for (entity e = world; (e = find(e, classname, "shownames_tag")); )
{
- // fade tag out if another tag that is closer to you overlaps
- entity e;
- for(e = world; (e = find(e, classname, "shownames_tag")); )
+ if (e == this) continue;
+ vector eo = project_3d_to_2d(e.origin);
+ if (eo.z < 0 || eo.x < 0 || eo.y < 0 || eo.x > vid_conwidth || eo.y > vid_conheight) continue;
+ eo.z = 0;
+ if (vlen((eX * o.x + eY * o.y) - eo) < autocvar_hud_shownames_antioverlap_distance
+ && dist > vlen(e.origin - view_origin))
{
- if(e == ent)
- continue;
- eo = project_3d_to_2d(e.origin);
- if (!(eo.z < 0 || eo.x < 0 || eo.y < 0 || eo.x > vid_conwidth || eo.y > vid_conheight))
- {
- eo.z = 0;
- if(vlen((eX * o.x + eY * o.y) - eo) < autocvar_hud_shownames_antioverlap_distance && vlen(ent.origin - view_origin) > vlen(e.origin - view_origin))
- {
- overlap = true;
- break;
- }
- }
- }
- }
-
- onscreen = (o.z >= 0 && o.x >= 0 && o.y >= 0 && o.x <= vid_conwidth && o.y <= vid_conheight);
- crosshairdistance = sqrt( pow(o.x - vid_conwidth/2, 2) + pow(o.y - vid_conheight/2, 2) );
-
- if(autocvar_hud_shownames_crosshairdistance)
- {
- if(autocvar_hud_shownames_crosshairdistance > crosshairdistance)
- ent.pointtime = time;
-
- if (ent.pointtime + autocvar_hud_shownames_crosshairdistance_time <= time)
overlap = true;
- else
- overlap = (autocvar_hud_shownames_crosshairdistance_antioverlap ? overlap : false); // override what antioverlap says unless allowed by cvar.
- }
-
- if(!ent.fadedelay)
- ent.fadedelay = time + SHOWNAMES_FADEDELAY;
-
- if(!ent.sameteam && (!onscreen || !hit)) // out of view, fade out
- {
- ent.alpha = max(0, ent.alpha - SHOWNAMES_FADESPEED * frametime);
- ent.fadedelay = 0; // reset fade in delay, enemy has left the view
- }
- else if(ent.csqcmodel_isdead) // dead player, fade out slowly
- ent.alpha = max(0, ent.alpha - SHOWNAMES_FADESPEED * 0.25 * frametime);
- else if(overlap) // tag overlap detected, fade out
- ent.alpha = max(0, ent.alpha - SHOWNAMES_FADESPEED * frametime);
- else if(ent.sameteam) // fade in for team mates
- ent.alpha = min(1, ent.alpha + SHOWNAMES_FADESPEED * frametime);
- else if(time > ent.fadedelay) // fade in for enemies
- ent.alpha = min(1, ent.alpha + SHOWNAMES_FADESPEED * frametime);
-
- // multiply by player alpha
- if(!ent.sameteam || (ent.sv_entnum == player_localentnum))
- ent.alpha *= getplayeralpha(ent.sv_entnum-1);
-
- if(ent.alpha < ALPHA_MIN_VISIBLE && gametype != MAPINFO_TYPE_CTS)
- return;
-
- float dist;
- dist = vlen(ent.origin - view_origin);
-
- float a;
- a = autocvar_hud_shownames_alpha;
- a *= ent.alpha;
- if(autocvar_hud_shownames_maxdistance)
- {
- if(dist >= autocvar_hud_shownames_maxdistance)
- return;
- a *= ((autocvar_hud_shownames_maxdistance - autocvar_hud_shownames_mindistance) - max(0, dist - autocvar_hud_shownames_mindistance)) / (autocvar_hud_shownames_maxdistance - autocvar_hud_shownames_mindistance);
+ break;
+ }
}
-
- if(!a)
- return;
-
- float resize;
- resize = 1;
- if(autocvar_hud_shownames_resize) // limit resize so its never smaller than 0.5... gets unreadable
- resize = 0.5 + 0.5 * ((autocvar_hud_shownames_maxdistance - autocvar_hud_shownames_mindistance) - max(0, dist - autocvar_hud_shownames_mindistance)) / (autocvar_hud_shownames_maxdistance - autocvar_hud_shownames_mindistance);
-
- // draw the sprite image
- if(o.z >= 0)
+ }
+ bool onscreen = (o.z >= 0 && o.x >= 0 && o.y >= 0 && o.x <= vid_conwidth && o.y <= vid_conheight);
+ float crosshairdistance = sqrt(pow(o.x - vid_conwidth / 2, 2) + pow(o.y - vid_conheight / 2, 2));
+ if (autocvar_hud_shownames_crosshairdistance)
+ {
+ if (autocvar_hud_shownames_crosshairdistance > crosshairdistance) this.pointtime = time;
+ if (this.pointtime + autocvar_hud_shownames_crosshairdistance_time <= time) overlap = true;
+ else overlap = (autocvar_hud_shownames_crosshairdistance_antioverlap ? overlap : false); // override what antioverlap says unless allowed by cvar.
+ }
+ if (!this.fadedelay) this.fadedelay = time + SHOWNAMES_FADEDELAY;
+ if (this.csqcmodel_isdead) // dead player, fade out slowly
+ {
+ this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * 0.25 * frametime);
+ }
+ else if (!this.sameteam && (!onscreen || !hit)) // out of view, fade out
+ {
+ this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * frametime);
+ this.fadedelay = 0; // reset fade in delay, enemy has left the view
+ }
+ else if (overlap) // tag overlap detected, fade out
+ {
+ this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * frametime);
+ }
+ else if (this.sameteam) // fade in for team mates
+ {
+ this.alpha = min(1, this.alpha + SHOWNAMES_FADESPEED * frametime);
+ }
+ else if (time > this.fadedelay) // fade in for enemies
+ {
+ this.alpha = min(1, this.alpha + SHOWNAMES_FADESPEED * frametime);
+ }
+ float a = autocvar_hud_shownames_alpha * this.alpha;
+ // multiply by player alpha
+ if (!this.sameteam || (this.sv_entnum == player_localentnum))
+ {
+ float f = getplayeralpha(this.sv_entnum - 1);
+ if (f == 0) f = 1;
+ if (f < 0) f = 0;
+ // FIXME: alpha is negative when dead, breaking death fade
+ if (!this.csqcmodel_isdead) a *= f;
+ }
+ if (a < ALPHA_MIN_VISIBLE && gametype != MAPINFO_TYPE_CTS) return;
+ if (autocvar_hud_shownames_maxdistance)
+ {
+ if (dist >= autocvar_hud_shownames_maxdistance) return;
+ float f = autocvar_hud_shownames_maxdistance - autocvar_hud_shownames_mindistance;
+ a *= (f - max(0, dist - autocvar_hud_shownames_mindistance)) / f;
+ }
+ if (!a) return;
+ float resize = 1;
+ if (autocvar_hud_shownames_resize) // limit resize so its never smaller than 0.5... gets unreadable
+ {
+ float f = autocvar_hud_shownames_maxdistance - autocvar_hud_shownames_mindistance;
+ resize = 0.5 + 0.5 * (f - max(0, dist - autocvar_hud_shownames_mindistance)) / f;
+ }
+ // draw the sprite image
+ if (o.z >= 0)
+ {
+ o.z = 0;
+ vector mySize = (eX * autocvar_hud_shownames_aspect + eY) * autocvar_hud_shownames_fontsize;
+ vector myPos = o - '0.5 0 0' * mySize.x - '0 1 0' * mySize.y;
+ // size scaling
+ mySize.x *= resize;
+ mySize.y *= resize;
+ myPos.x += 0.5 * (mySize.x / resize - mySize.x);
+ myPos.y += (mySize.y / resize - mySize.y);
+ // this is where the origin of the string
+ vector namepos = myPos;
+ float namewidth = mySize.x;
+ if (autocvar_hud_shownames_status && this.sameteam)
{
- o.z = 0;
-
- vector myPos, mySize;
- mySize = (eX * autocvar_hud_shownames_aspect + eY) * autocvar_hud_shownames_fontsize;
- myPos = o - '0.5 0 0' * mySize.x - '0 1 0' * mySize.y;
-
- // size scaling
- mySize.x *= resize;
- mySize.y *= resize;
-
- myPos.x += 0.5 * (mySize.x / resize - mySize.x);
- myPos.y += (mySize.y / resize - mySize.y);
-
- vector namepos; // this is where the origin of the string
- float namewidth;
-
- namepos = myPos;
- namewidth = mySize.x;
-
- if(autocvar_hud_shownames_status && teamplay)
+ vector v = namepos + '0 1 0' * autocvar_hud_shownames_fontsize * resize;
+ vector s = eX * 0.5 * mySize.x + eY * resize * autocvar_hud_shownames_statusbar_height;
+ if (this.healthvalue > 0)
{
- if(ent.sameteam)
- {
- if(ent.healthvalue > 0)
- {
- HUD_Panel_DrawProgressBar(namepos + '0 1 0' * autocvar_hud_shownames_fontsize * resize, eX * 0.5 * mySize.x + eY * resize * autocvar_hud_shownames_statusbar_height, "nametag_statusbar", ent.healthvalue/autocvar_hud_panel_healtharmor_maxhealth, 0, 1, '1 0 0', a, DRAWFLAG_NORMAL);
-
- if(ent.armorvalue > 0)
- HUD_Panel_DrawProgressBar(namepos + '0 1 0' * autocvar_hud_shownames_fontsize * resize + eX * 0.5 * mySize.x, eX * 0.5 * mySize.x + eY * resize * autocvar_hud_shownames_statusbar_height, "nametag_statusbar", ent.armorvalue/autocvar_hud_panel_healtharmor_maxarmor, 0, 0, '0 1 0', a, DRAWFLAG_NORMAL);
- }
- }
+ HUD_Panel_DrawProgressBar(v, s, "nametag_statusbar",
+ this.healthvalue / autocvar_hud_panel_healtharmor_maxhealth, false, 1, '1 0 0', a,
+ DRAWFLAG_NORMAL);
+ }
+ if (this.armorvalue > 0)
+ {
+ HUD_Panel_DrawProgressBar(v + eX * 0.5 * mySize.x, s, "nametag_statusbar",
+ this.armorvalue / autocvar_hud_panel_healtharmor_maxarmor, false, 0, '0 1 0', a,
+ DRAWFLAG_NORMAL);
}
-
- string s;
- s = GetPlayerName(ent.sv_entnum-1);
- if((autocvar_hud_shownames_decolorize == 1 && teamplay) || autocvar_hud_shownames_decolorize == 2)
- s = playername(s, GetPlayerColor(ent.sv_entnum-1));
-
- drawfontscale = '1 1 0' * resize;
- s = textShortenToWidth(s, namewidth, '1 1 0' * autocvar_hud_shownames_fontsize, stringwidth_colors);
-
- float width;
- width = stringwidth(s, true, '1 1 0' * autocvar_hud_shownames_fontsize);
-
- if (width != namewidth)
- namepos.x += (namewidth - width) / 2;
- drawcolorcodedstring(namepos, s, '1 1 0' * autocvar_hud_shownames_fontsize, a, DRAWFLAG_NORMAL);
- drawfontscale = '1 1 0';
}
+ string s = GetPlayerName(this.sv_entnum - 1);
+ if ((autocvar_hud_shownames_decolorize == 1 && teamplay)
+ || autocvar_hud_shownames_decolorize == 2) s = playername(s, GetPlayerColor(this.sv_entnum - 1));
+ drawfontscale = '1 1 0' * resize;
+ s = textShortenToWidth(s, namewidth, '1 1 0' * autocvar_hud_shownames_fontsize, stringwidth_colors);
+ float width = stringwidth(s, true, '1 1 0' * autocvar_hud_shownames_fontsize);
+ if (width != namewidth) namepos.x += (namewidth - width) / 2;
+ drawcolorcodedstring(namepos, s, '1 1 0' * autocvar_hud_shownames_fontsize, a, DRAWFLAG_NORMAL);
+ drawfontscale = '1 1 0';
}
}
-entity shownames_ent[255];
-void Draw_ShowNames_All()
+LinkedList shownames_ent;
+STATIC_INIT(shownames_ent)
{
- int i;
- for(i = 0; i < maxclients; ++i)
+ shownames_ent = LL_NEW();
+ for (int i = 0; i < maxclients; ++i)
{
- float t;
- t = GetPlayerColor(i);
- if(t == NUM_SPECTATOR)
- continue;
-
- entity e;
- e = shownames_ent[i];
- if(!e)
- {
- e = new(shownames_tag);
- e.sv_entnum = i+1;
- shownames_ent[i] = e;
- }
+ entity e = new(shownames_tag);
+ e.sv_entnum = i + 1;
+ LL_PUSH(shownames_ent, e);
+ }
+}
- entity entcs;
- entcs = entcs_receiver[i];
- if(entcs)
+void Draw_ShowNames_All()
+{
+ if (!autocvar_hud_shownames) return;
+ LL_EACH(shownames_ent, true, LAMBDA(
+ entity entcs = entcs_receiver(i);
+ if (!entcs) continue;
+ if (entcs.m_entcs_private)
{
- e.healthvalue = entcs.healthvalue;
- e.armorvalue = entcs.armorvalue;
- e.sameteam = 1; /* (teamplay && (t == myteam)); */
+ it.healthvalue = entcs.healthvalue;
+ it.armorvalue = entcs.armorvalue;
+ it.sameteam = true;
}
else
{
- e.healthvalue = 2342;
- e.armorvalue = 0;
- e.sameteam = 0;
+ it.healthvalue = 0;
+ it.armorvalue = 0;
+ it.sameteam = false;
}
-
- setorigin(e, getplayerorigin(i));
- if(e.origin == GETPLAYERORIGIN_ERROR)
- continue;
-
- e.csqcmodel_isdead = getplayerisdead(i);
-
- Draw_ShowNames(e);
- }
+ bool dead = getplayerisdead(i);
+ if (!it.csqcmodel_isdead && entcs.has_origin) setorigin(it, entcs.origin);
+ it.csqcmodel_isdead = dead;
+ Draw_ShowNames(it);
+ ));
}
-#include "../common/buffs/all.qh"
#include "../common/movetypes/movetypes.qh"
#include "../common/weapons/all.qh"
#include "../lib/csqcmodel/cl_model.qh"
{
int sendflags = ReadByte();
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
self.iflags = IFLAG_VELOCITY | IFLAG_ORIGIN;
self.classname = "radarlink";
return = true;
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
}
#include "../common/debug.qh"
#include "../common/mapinfo.qh"
#include "../common/gamemodes/all.qh"
-#include "../common/nades/all.qh"
+#include "../common/physics.qh"
#include "../common/stats.qh"
#include "../common/triggers/target/music.qh"
#include "../common/teams.qh"
break;
}
- vector traceorigin = getplayerorigin(player_localentnum-1) + (eZ * getstati(STAT_VIEWHEIGHT));
+ vector traceorigin = entcs_receiver(player_localentnum - 1).origin + (eZ * getstati(STAT_VIEWHEIGHT));
vecs = decompressShotOrigin(STAT(SHOTORG));
return true;
if(MUTATOR_CALLHOOK(WantEventchase, self))
return true;
- if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_NEXBALL.m_id)))
+ if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WEPSET(NEXBALL)))
return true;
if(autocvar_cl_eventchase_death && (getstati(STAT_HEALTH) <= 0))
{
wcross_color = stov(autocvar_crosshair_dot_color);
CROSSHAIR_DRAW(wcross_resolution * autocvar_crosshair_dot_size, "gfx/crosshairdot.tga", f * autocvar_crosshair_dot_alpha);
- // FIXME why don't we use wcross_alpha here?cl_notice_run();
+ // FIXME why don't we use wcross_alpha here?
wcross_color = wcross_color_old;
}
}
void HUD_Draw()
{
- if(STAT(FROZEN))
- drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((STAT(REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * STAT(REVIVE_PROGRESS)) + ('0 1 1' * STAT(REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
- else if (STAT(HEALING_ORB)>time)
- drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, NADE_TYPE_HEAL.m_color, autocvar_hud_colorflash_alpha*STAT(HEALING_ORB_ALPHA), DRAWFLAG_ADDITIVE);
+ vector rgb = '0 0 0';
+ float a = 1;
+ if (MUTATOR_CALLHOOK(HUD_Draw_overlay))
+ {
+ rgb = MUTATOR_ARGV(0, vector);
+ a = MUTATOR_ARGV(0, float);
+ }
+ else if(STAT(FROZEN))
+ {
+ rgb = ((STAT(REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * STAT(REVIVE_PROGRESS)) + ('0 1 1' * STAT(REVIVE_PROGRESS) * -1)) : '0.25 0.90 1');
+ }
+ drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, rgb, autocvar_hud_colorflash_alpha * a, DRAWFLAG_ADDITIVE);
if(!intermission)
if(STAT(NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death
{
float oldr_useportalculling;
float oldr_useinfinitefarclip;
-const int BUTTON_3 = 4;
-const int BUTTON_4 = 8;
-float cl_notice_run();
+void cl_notice_run();
float prev_myteam;
int lasthud;
float vh_notice_time;
else
view_quality = 1;
- button_attack2 = (input_buttons & BUTTON_3);
- button_zoom = (input_buttons & BUTTON_4);
+ button_attack2 = PHYS_INPUT_BUTTON_ATCK2(self);
+ button_zoom = PHYS_INPUT_BUTTON_ZOOM(self);
vf_size = getpropertyvec(VF_SIZE);
vf_min = getpropertyvec(VF_MIN);
mousepos = mousepos*0.5 + getmousepos();
*/
- for(entity e = NULL; (e = nextent(e)); ) if (e.draw) {
- WITH(entity, self, e, e.draw(e));
- }
+ FOREACH_ENTITY(it.draw, LAMBDA(WITH(entity, self, it, it.draw(it))));
addentities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
renderscene();
} else */
// draw 2D entities
- for (entity e = NULL; (e = nextent(e)); ) if (e.draw2d) {
- WITH(entity, self, e, e.draw2d(e));
- }
+ FOREACH_ENTITY(it.draw2d, LAMBDA(WITH(entity, self, it, it.draw2d(it))));
Draw_ShowNames_All();
Debug_Draw();
}
}
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(self);
self.saved = self.(fld);
int f;
var .vector fld;
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
self.iflags = IFLAG_ANGLES | IFLAG_ORIGIN;
if(self.bgmscriptangular)
return = true;
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
self.saved = self.(fld);
#include "../../common/constants.qh"
#include "../../common/movetypes/movetypes.qh"
-#include "../../common/nades/all.qh"
#include "../../lib/csqcmodel/interpolate.qh"
}
}
+bool Projectile_isnade(int proj); // TODO: remove
+
void Projectile_Draw(entity this)
{
vector rot;
}
else
{
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(self);
}
if (self.count & 0x80)
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
+ if (Projectile_isnade(self.cnt))
rot = self.avelocity;
self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
+ if (Projectile_isnade(self.cnt))
trailorigin += v_up * 4;
if (drawn)
}
if (!(self.count & 0x80))
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
if (f & 1)
{
CASE(HOOKBOMB) self.traileffect = EFFECT_TR_KNIGHTSPIKE.m_id; break;
CASE(HAGAR) self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
CASE(HAGAR_BOUNCING) self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
- CASE(NAPALM_FOUNTAIN) // fallthrough // sself.modelindex = 0; self.traileffect = _particleeffectnum("torch_small"); break;
CASE(FIREBALL) self.modelindex = 0; self.traileffect = EFFECT_FIREBALL.m_id; break; // particle effect is good enough
CASE(FIREMINE) self.modelindex = 0; self.traileffect = EFFECT_FIREMINE.m_id; break; // particle effect is good enough
CASE(TAG) self.traileffect = EFFECT_TR_ROCKET.m_id; break;
if (MUTATOR_CALLHOOK(Ent_Projectile, self))
break;
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
- {
- setmodel(self, MDL_PROJECTILE_NADE);
- entity trail = Nade_TrailEffect(self.cnt, self.team);
- if (trail.eent_eff_name) self.traileffect = trail.m_id;
- break;
- }
error("Received invalid CSQC projectile, can't work with this!");
break;
}
self.move_movetype = MOVETYPE_BOUNCE;
self.move_touch = func_null;
break;
- case PROJECTILE_NAPALM_FOUNTAIN:
case PROJECTILE_FIREBALL:
loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY2), VOL_BASE, ATTEN_NORM);
self.mins = '-16 -16 -16';
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
- {
- entity nade_type = Nade_FromProjectile(self.cnt);
- self.mins = '-16 -16 -16';
- self.maxs = '16 16 16';
- self.colormod = nade_type.m_color;
- self.move_movetype = MOVETYPE_BOUNCE;
- self.move_touch = func_null;
- self.scale = 1.5;
- self.avelocity = randomvec() * 720;
-
- if (nade_type == NADE_TYPE_TRANSLOCATE || nade_type == NADE_TYPE_SPAWN)
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
- else
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
- }
-
MUTATOR_CALLHOOK(EditProjectile, self);
setsize(self, self.mins, self.maxs);
}
if (!(self.count & 0x80))
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
self.classname = "csqcprojectile";
self.draw = Projectile_Draw;
+++ /dev/null
-REGISTER_BUFF(AMMO) {
- this.m_prettyName = _("Ammo");
- this.m_name = "ammo";
- this.m_skin = 3;
- this.m_color = '0.76 1 0.1';
-}
-BUFF_SPAWNFUNCS(ammo, BUFF_AMMO)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(ammoregen, BUFF_AMMO)
-
-REGISTER_BUFF(RESISTANCE) {
- this.m_prettyName = _("Resistance");
- this.m_name = "resistance";
- this.m_skin = 0;
- this.m_color = '0.36 1 0.07';
-}
-BUFF_SPAWNFUNCS(resistance, BUFF_RESISTANCE)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(resistance, BUFF_RESISTANCE)
-
-REGISTER_BUFF(SPEED) {
- this.m_prettyName = _("Speed");
- this.m_name = "speed";
- this.m_skin = 9;
- this.m_color = '0.1 1 0.84';
-}
-BUFF_SPAWNFUNCS(speed, BUFF_SPEED)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(haste, BUFF_SPEED)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(scout, BUFF_SPEED)
-
-REGISTER_BUFF(MEDIC) {
- this.m_prettyName = _("Medic");
- this.m_name = "medic";
- this.m_skin = 1;
- this.m_color = '1 0.12 0';
-}
-BUFF_SPAWNFUNCS(medic, BUFF_MEDIC)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler, BUFF_MEDIC)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(medic, BUFF_MEDIC)
-
-REGISTER_BUFF(BASH) {
- this.m_prettyName = _("Bash");
- this.m_name = "bash";
- this.m_skin = 5;
- this.m_color = '1 0.39 0';
-}
-BUFF_SPAWNFUNCS(bash, BUFF_BASH)
-
-REGISTER_BUFF(VAMPIRE) {
- this.m_prettyName = _("Vampire");
- this.m_name = "vampire";
- this.m_skin = 2;
- this.m_color = '1 0 0.24';
-}
-BUFF_SPAWNFUNCS(vampire, BUFF_VAMPIRE)
-
-REGISTER_BUFF(DISABILITY) {
- this.m_prettyName = _("Disability");
- this.m_name = "disability";
- this.m_skin = 7;
- this.m_color = '0.94 0.3 1';
-}
-BUFF_SPAWNFUNCS(disability, BUFF_DISABILITY)
-
-REGISTER_BUFF(VENGEANCE) {
- this.m_prettyName = _("Vengeance");
- this.m_name = "vengeance";
- this.m_skin = 15;
- this.m_color = '1 0.23 0.61';
-}
-BUFF_SPAWNFUNCS(vengeance, BUFF_VENGEANCE)
-
-REGISTER_BUFF(JUMP) {
- this.m_prettyName = _("Jump");
- this.m_name = "jump";
- this.m_skin = 10;
- this.m_color = '0.24 0.78 1';
-}
-BUFF_SPAWNFUNCS(jump, BUFF_JUMP)
-
-REGISTER_BUFF(FLIGHT) {
- this.m_prettyName = _("Flight");
- this.m_name = "flight";
- this.m_skin = 11;
- this.m_color = '0.33 0.56 1';
-}
-BUFF_SPAWNFUNCS(flight, BUFF_FLIGHT)
-
-REGISTER_BUFF(INVISIBLE) {
- this.m_prettyName = _("Invisible");
- this.m_name = "invisible";
- this.m_skin = 12;
- this.m_color = '0.5 0.5 1';
-}
-BUFF_SPAWNFUNCS(invisible, BUFF_INVISIBLE)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(invis, BUFF_INVISIBLE)
-
-REGISTER_BUFF(INFERNO) {
- this.m_prettyName = _("Inferno");
- this.m_name = "inferno";
- this.m_skin = 16;
- this.m_color = '1 0.62 0';
-}
-BUFF_SPAWNFUNCS(inferno, BUFF_INFERNO)
-
-REGISTER_BUFF(SWAPPER) {
- this.m_prettyName = _("Swapper");
- this.m_name = "swapper";
- this.m_skin = 17;
- this.m_color = '0.63 0.36 1';
-}
-BUFF_SPAWNFUNCS(swapper, BUFF_SWAPPER)
-
-REGISTER_BUFF(MAGNET) {
- this.m_prettyName = _("Magnet");
- this.m_name = "magnet";
- this.m_skin = 18;
- this.m_color = '1 0.95 0.18';
-}
-BUFF_SPAWNFUNCS(magnet, BUFF_MAGNET)
+++ /dev/null
-#if defined(CSQC)
- #include "../../client/defs.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
-#endif
-#include "all.qh"
-
+++ /dev/null
-#ifndef BUFFS_ALL_H
-#define BUFFS_ALL_H
-// Welcome to the stuff behind the scenes
-// Below, you will find the list of buffs
-// Add new buffs here!
-// Note: Buffs also need spawnfuncs, which are set below
-
-#include "../teams.qh"
-#include "../util.qh"
-
-REGISTRY(Buffs, BITS(4))
-#define Buffs_from(i) _Buffs_from(i, BUFF_Null)
-REGISTER_REGISTRY(RegisterBuffs)
-REGISTRY_CHECK(Buffs)
-
-#define REGISTER_BUFF(id) \
- REGISTER(RegisterBuffs, BUFF, Buffs, id, m_id, NEW(Buff)); \
- REGISTER_INIT_POST(BUFF, id) { \
- this.netname = this.m_name; \
- this.m_itemid = BIT(this.m_id - 1); \
- this.m_sprite = strzone(strcat("buff-", this.m_name)); \
- } \
- REGISTER_INIT(BUFF, id)
-
-#include "../items/item/pickup.qh"
-CLASS(Buff, Pickup)
- /** bit index */
- ATTRIB(Buff, m_itemid, int, 0)
- ATTRIB(Buff, m_name, string, "buff")
- ATTRIB(Buff, m_color, vector, '1 1 1')
- ATTRIB(Buff, m_prettyName, string, "Buff")
- ATTRIB(Buff, m_skin, int, 0)
- ATTRIB(Buff, m_sprite, string, "")
- METHOD(Buff, display, void(entity this, void(string name, string icon) returns)) {
- returns(this.m_prettyName, sprintf("/gfx/hud/%s/buff_%s", cvar_string("menu_skin"), this.m_name));
- }
-#ifdef SVQC
- METHOD(Buff, m_time, float(entity));
- float Buff_m_time(entity this) { return cvar(strcat("g_buffs_", this.netname, "_time")); }
-#endif
-ENDCLASS(Buff)
-
-#ifdef SVQC
- .int buffs = _STAT(BUFFS);
- void buff_Init(entity ent);
- void buff_Init_Compat(entity ent, entity replacement);
- #define BUFF_SPAWNFUNC(e, b, t) spawnfunc(item_buff_##e) { \
- self.buffs = b.m_itemid; \
- self.team = t; \
- buff_Init(self); \
- }
- #define BUFF_SPAWNFUNCS(e, b) \
- BUFF_SPAWNFUNC(e, b, 0) \
- BUFF_SPAWNFUNC(e##_team1, b, NUM_TEAM_1) \
- BUFF_SPAWNFUNC(e##_team2, b, NUM_TEAM_2) \
- BUFF_SPAWNFUNC(e##_team3, b, NUM_TEAM_3) \
- BUFF_SPAWNFUNC(e##_team4, b, NUM_TEAM_4)
- #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r) spawnfunc(item_##o) { buff_Init_Compat(self, r); }
-#else
- #define BUFF_SPAWNFUNC(e, b, t)
- #define BUFF_SPAWNFUNCS(e, b)
- #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r)
-#endif
-
-REGISTER_BUFF(Null);
-BUFF_SPAWNFUNCS(random, BUFF_Null)
-
-#include "all.inc"
-
-#endif
#include "command.qh"
REGISTRY(GENERIC_COMMANDS, BITS(7))
#define GENERIC_COMMANDS_from(i) _GENERIC_COMMANDS_from(i, NULL)
-REGISTER_REGISTRY(RegisterGENERIC_COMMANDS)
-REGISTRY_SORT(GENERIC_COMMANDS, 0)
+REGISTER_REGISTRY(GENERIC_COMMANDS)
+REGISTRY_SORT(GENERIC_COMMANDS)
#define GENERIC_COMMAND(id, description) \
CLASS(genericcommand_##id, Command) \
ATTRIB(genericcommand_##id, m_name, string, #id); \
ATTRIB(genericcommand_##id, m_description, string, description); \
ENDCLASS(genericcommand_##id) \
- REGISTER(RegisterGENERIC_COMMANDS, CMD_G, GENERIC_COMMANDS, id, m_id, NEW(genericcommand_##id)); \
+ REGISTER(GENERIC_COMMANDS, CMD_G, id, m_id, NEW(genericcommand_##id)); \
METHOD(genericcommand_##id, m_invokecmd, void(int request, int arguments, string command))
STATIC_INIT(GENERIC_COMMANDS_aliases) {
/** Sent as a temp entity from a persistent linked entity */
REGISTER_NET_TEMP(ENT_CLIENT_INIT)
-REGISTER_NET_LINKED(ENT_CLIENT_ENTCS)
REGISTER_NET_LINKED(ENT_CLIENT_SCORES_INFO)
REGISTER_NET_LINKED(ENT_CLIENT_SCORES)
REGISTER_NET_LINKED(ENT_CLIENT_TEAMSCORES)
const int SP_DMGTAKEN = 11;
// game mode specific indices are not in common/, but in server/scores_rules.qc!
-const int CH_INFO = 0;
-const int CH_TRIGGER = -3;
-const int CH_WEAPON_A = -1;
-const int CH_WEAPON_SINGLE = 1;
-const int CH_VOICE = -2;
-const int CH_BGM_SINGLE = 8;
-const int CH_AMBIENT = -9;
-const int CH_TRIGGER_SINGLE = 3;
-const int CH_SHOTS = -4;
-const int CH_SHOTS_SINGLE = 4;
-const int CH_WEAPON_B = -1;
-const int CH_PAIN = -6;
-const int CH_PAIN_SINGLE = 6;
-const int CH_PLAYER = -7;
-const int CH_PLAYER_SINGLE = 7;
-const int CH_TUBA_SINGLE = 5;
-
-const float ATTEN_NONE = 0;
-const float ATTEN_MIN = 0.015625;
-const float ATTEN_NORM = 0.5;
-const float ATTEN_LARGE = 1;
-const float ATTEN_IDLE = 2;
-const float ATTEN_STATIC = 3;
-const float ATTEN_MAX = 3.984375;
-
-const float VOL_BASE = 0.7;
-const float VOL_BASEVOICE = 1.0;
-
// WEAPONTODO: move this into separate/new projectile handling code // this sets sounds and other properties of the projectiles in csqc
const int PROJECTILE_ELECTRO = 1;
const int PROJECTILE_ROCKET = 2;
CSQCModel_Hook_PostUpdate(isnew, isplayer, islocalplayer);
#define CSQCMODEL_HOOK_PREDRAW \
CSQCModel_Hook_PreDraw(isplayer);
-#define CSQCPLAYER_HOOK_POSTCAMERASETUP \
- CSQCPlayer_SetViewLocation();
+#define CSQCPLAYER_HOOK_POSTCAMERASETUP() \
+ CSQCPlayer_SetViewLocation()
// force updates of player entities that often even if unchanged
#ifndef CSQCPLAYER_FORCE_UPDATES
REGISTRY(Deathtypes, BITS(8))
#define Deathtypes_from(i) _Deathtypes_from(i, NULL)
-REGISTER_REGISTRY(RegisterDeathtypes)
+REGISTER_REGISTRY(Deathtypes)
REGISTRY_CHECK(Deathtypes)
.entity death_msgself;
.string death_msgextra;
#define REGISTER_DEATHTYPE(id, msg_death, msg_death_by, extra) \
- REGISTER(RegisterDeathtypes, DEATH, Deathtypes, id, m_id, new(deathtype)) { \
+ REGISTER(Deathtypes, DEATH, id, m_id, new(deathtype)) { \
make_pure(this); \
this.m_id += DT_FIRST; \
this.nent_name = #id; \
static int debugdraw_frame;
++debugdraw_frame;
const int size = 8;
- for (entity e1 = NULL; (e1 = nextent(e1)); )
- {
- if (e1.debugdraw_last == debugdraw_frame) continue;
+ FOREACH_ENTITY(true, LAMBDA(
+ if (it.debugdraw_last == debugdraw_frame) continue;
int ofs = 0;
- for (entity e = findradius(e1.origin, 100); e; e = e.chain)
+ for (entity e = findradius(it.origin, 100); e; e = e.chain)
{
if (e.debugdraw_last == debugdraw_frame) continue;
e.debugdraw_last = debugdraw_frame;
size * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL);
++ofs;
}
- }
+ ));
}
#endif
EFFECT(0, SPAWNPOINT_NEUTRAL, "spawn_point_neutral")
EFFECT(0, SPAWN_NEUTRAL, "spawn_event_neutral")
-EFFECT(0, NADE_EXPLODE_RED, "nade_red_explode")
-EFFECT(0, NADE_EXPLODE_BLUE, "nade_blue_explode")
-EFFECT(0, NADE_EXPLODE_YELLOW, "nade_yellow_explode")
-EFFECT(0, NADE_EXPLODE_PINK, "nade_pink_explode")
-EFFECT(0, NADE_EXPLODE_NEUTRAL, "nade_neutral_explode")
-entity EFFECT_NADE_EXPLODE(int teamid)
-{
- switch (teamid) {
- case NUM_TEAM_1: return EFFECT_NADE_EXPLODE_RED;
- case NUM_TEAM_2: return EFFECT_NADE_EXPLODE_BLUE;
- case NUM_TEAM_3: return EFFECT_NADE_EXPLODE_YELLOW;
- case NUM_TEAM_4: return EFFECT_NADE_EXPLODE_PINK;
- default: return EFFECT_NADE_EXPLODE_NEUTRAL;
- }
-}
-
-EFFECT(1, NADE_TRAIL_RED, "nade_red")
-EFFECT(1, NADE_TRAIL_BLUE, "nade_blue")
-EFFECT(1, NADE_TRAIL_YELLOW, "nade_yellow")
-EFFECT(1, NADE_TRAIL_PINK, "nade_pink")
-EFFECT(1, NADE_TRAIL_NEUTRAL, "nade_neutral")
-entity EFFECT_NADE_TRAIL(int teamid)
-{
- switch (teamid) {
- case NUM_TEAM_1: return EFFECT_NADE_TRAIL_RED;
- case NUM_TEAM_2: return EFFECT_NADE_TRAIL_BLUE;
- case NUM_TEAM_3: return EFFECT_NADE_TRAIL_YELLOW;
- case NUM_TEAM_4: return EFFECT_NADE_TRAIL_PINK;
- default: return EFFECT_NADE_TRAIL_NEUTRAL;
- }
-}
-
-EFFECT(1, NADE_TRAIL_BURN_RED, "nade_red_burn")
-EFFECT(1, NADE_TRAIL_BURN_BLUE, "nade_blue_burn")
-EFFECT(1, NADE_TRAIL_BURN_YELLOW, "nade_yellow_burn")
-EFFECT(1, NADE_TRAIL_BURN_PINK, "nade_pink_burn")
-EFFECT(1, NADE_TRAIL_BURN_NEUTRAL, "nade_neutral_burn")
-entity EFFECT_NADE_TRAIL_BURN(int teamid)
-{
- switch (teamid) {
- case NUM_TEAM_1: return EFFECT_NADE_TRAIL_BURN_RED;
- case NUM_TEAM_2: return EFFECT_NADE_TRAIL_BURN_BLUE;
- case NUM_TEAM_3: return EFFECT_NADE_TRAIL_BURN_YELLOW;
- case NUM_TEAM_4: return EFFECT_NADE_TRAIL_BURN_PINK;
- default: return EFFECT_NADE_TRAIL_BURN_NEUTRAL;
- }
-}
-
EFFECT(0, ICEORGLASS, "iceorglass")
EFFECT(0, ICEFIELD, "icefield")
EFFECT(0, FIREFIELD, "firefield")
REGISTRY(Effects, BITS(8))
#define Effects_from(i) _Effects_from(i, EFFECT_Null)
-REGISTER_REGISTRY(RegisterEffects)
+REGISTER_REGISTRY(Effects)
REGISTRY_CHECK(Effects)
#define EFFECT(istrail, name, realname) \
- REGISTER(RegisterEffects, EFFECT, Effects, name, m_id, Create_Effect_Entity(realname, istrail));
+ REGISTER(Effects, EFFECT, name, m_id, Create_Effect_Entity(realname, istrail));
EFFECT(0, Null, string_null)
#include "all.inc"
REGISTRY(EffectInfos, BITS(9))
#define EffectInfos_from(i) _EffectInfos_from(i, NULL)
-REGISTER_REGISTRY(RegisterEffectInfos)
+REGISTER_REGISTRY(EffectInfos)
#define EFFECTINFO(name) \
[[accumulate]] void effectinfo_##name(EffectInfoGroup parent, EffectInfo this) { } \
- REGISTER(RegisterEffectInfos, EFFECTINFO, EffectInfos, name, m_id, NEW(EffectInfoGroup)) { \
+ REGISTER(EffectInfos, EFFECTINFO, name, m_id, NEW(EffectInfoGroup)) { \
effectinfo_##name(this, NULL); \
}
#include "casings.qc"
#include "damageeffects.qc"
#include "gibs.qc"
+#include "globalsound.qc"
#include "lightningarc.qc"
#include "modeleffects.qc"
#ifdef CSQC
#include "../../deathtypes/all.qh"
#include "../../movetypes/movetypes.qh"
+#include "../../../client/mutators/events.qh"
#include "../../vehicles/all.qh"
#include "../../weapons/all.qh"
#endif
w_backoff = -1 * normalize(force);
setorigin(self, w_org + w_backoff * 2); // for sound() calls
- if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) {
- hitwep.wr_impacteffect(hitwep);
+ if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY))
+ {
+ if(!MUTATOR_CALLHOOK(Weapon_ImpactEffect, hitwep))
+ hitwep.wr_impacteffect(hitwep);
}
}
}
--- /dev/null
+#include "globalsound.qh"
+
+#include "../common/ent_cs.qh"
+
+#ifdef IMPLEMENTATION
+ #include "../../animdecide.qh"
+
+ #ifdef SVQC
+ #include "../../../server/cl_player.qh"
+ #endif
+
+ REGISTER_NET_TEMP(globalsound)
+ REGISTER_NET_TEMP(playersound)
+
+ #ifdef SVQC
+ /**
+ * @param from the source entity, its position is sent
+ * @param gs the global sound def
+ * @param r a random number in 0..1
+ */
+ void globalsound(int channel, entity from, entity gs, float r, int chan, float vol, float atten)
+ {
+ if (channel == MSG_ONE && !IS_REAL_CLIENT(msg_entity)) return;
+ WriteHeader(channel, globalsound);
+ WriteByte(channel, gs.m_id);
+ WriteByte(channel, r * 255);
+ WriteByte(channel, etof(from));
+ WriteByte(channel, fabs(chan));
+ WriteByte(channel, floor(vol * 255));
+ WriteByte(channel, floor(atten * 64));
+ entcs_force_origin(from);
+ vector o = from.origin + 0.5 * (from.mins + from.maxs);
+ WriteCoord(channel, o.x);
+ WriteCoord(channel, o.y);
+ WriteCoord(channel, o.z);
+ }
+
+ /**
+ * @param from the source entity, its position is sent
+ * @param ps the player sound def
+ * @param r a random number in 0..1
+ */
+ void playersound(int channel, entity from, entity ps, float r, int chan, float vol, float atten)
+ {
+ if (channel == MSG_ONE && !IS_REAL_CLIENT(msg_entity)) return;
+ WriteHeader(channel, playersound);
+ WriteByte(channel, ps.m_id);
+ WriteByte(channel, r * 255);
+ WriteByte(channel, etof(from));
+ WriteByte(channel, fabs(chan));
+ WriteByte(channel, floor(vol * 255));
+ WriteByte(channel, floor(atten * 64));
+ entcs_force_origin(from);
+ vector o = from.origin + 0.5 * (from.mins + from.maxs);
+ WriteCoord(channel, o.x);
+ WriteCoord(channel, o.y);
+ WriteCoord(channel, o.z);
+ }
+ #endif
+
+ string GlobalSound_sample(string pair, float r);
+
+ #ifdef CSQC
+
+ NET_HANDLE(globalsound, bool isnew)
+ {
+ entity gs = GlobalSounds_from(ReadByte());
+ float r = ReadByte() / 255;
+ string sample = GlobalSound_sample(gs.m_globalsoundstr, r);
+ int who = ReadByte();
+ entity e = entcs_receiver(who - 1);
+ int chan = ReadByte();
+ float vol = ReadByte() / 255;
+ float atten = ReadByte() / 64;
+ vector o;
+ o.x = ReadCoord();
+ o.y = ReadCoord();
+ o.z = ReadCoord();
+ // TODO: is this really what we want to be doing? Footsteps that follow the player at head height?
+ if (who == player_currententnum) e = findfloat(world, entnum, who); // play at camera position for full volume
+ else if (e) e.origin = o;
+ if (e)
+ {
+ sound7(e, chan, sample, vol, atten, 0, 0);
+ }
+ else
+ {
+ entity e = new(globalsound);
+ e.origin = o;
+ sound8(e, o, chan, sample, vol, atten, 0, 0);
+ remove(e); // debug with: e.think = SUB_Remove; e.nextthink = time + 1;
+ }
+ return true;
+ }
+
+ NET_HANDLE(playersound, bool isnew)
+ {
+ entity ps = PlayerSounds_from(ReadByte());
+ float r = ReadByte() / 255;
+ int who = ReadByte();
+ entity e = entcs_receiver(who - 1);
+ UpdatePlayerSounds(e);
+ string s = e.(ps.m_playersoundfld);
+ string sample = GlobalSound_sample(s, r);
+ int chan = ReadByte();
+ float vol = ReadByte() / 255;
+ float atten = ReadByte() / 64;
+ vector o;
+ o.x = ReadCoord();
+ o.y = ReadCoord();
+ o.z = ReadCoord();
+ if (who == player_currententnum) e = findfloat(world, entnum, who); // play at camera position for full volume
+ else if (e) e.origin = o;
+ if (e)
+ {
+ // TODO: for non-visible players, origin should probably continue to be updated as long as the sound is playing
+ sound7(e, chan, sample, vol, atten, 0, 0);
+ }
+ else
+ {
+ LOG_WARNINGF("Missing entcs data for player %d\n", who);
+ // Can this happen?
+ entity e = new(playersound);
+ e.origin = o;
+ sound8(e, o, chan, sample, vol, atten, 0, 0);
+ remove(e); // debug with: e.think = SUB_Remove; e.nextthink = time + 1;
+ }
+ return true;
+ }
+
+ #endif
+
+ string GlobalSound_sample(string pair, float r)
+ {
+ int n;
+ {
+ string s = cdr(pair);
+ if (s) n = stof(s);
+ else n = 0;
+ }
+ string sample = car(pair);
+ if (n > 0) sample = sprintf("%s%d.wav", sample, floor(r * n + 1)); // randomization
+ else sample = sprintf("%s.wav", sample);
+ return sample;
+ }
+
+ void PrecacheGlobalSound(string sample)
+ {
+ int n;
+ {
+ string s = cdr(sample);
+ if (s) n = stof(s);
+ else n = 0;
+ }
+ sample = car(sample);
+ if (n > 0)
+ {
+ for (int i = 1; i <= n; ++i)
+ precache_sound(sprintf("%s%d.wav", sample, i));
+ }
+ else
+ {
+ precache_sound(sprintf("%s.wav", sample));
+ }
+ }
+
+ entity GetVoiceMessage(string type)
+ {
+ FOREACH(PlayerSounds, it.m_playersoundstr == type && it.instanceOfVoiceMessage == true, LAMBDA(return it));
+ return NULL;
+ }
+
+ entity GetPlayerSound(string type)
+ {
+ FOREACH(PlayerSounds, it.m_playersoundstr == type && it.instanceOfVoiceMessage == false, LAMBDA(return it));
+ return NULL;
+ }
+
+ string allvoicesamples;
+ STATIC_INIT(allvoicesamples)
+ {
+ FOREACH(PlayerSounds, it.instanceOfVoiceMessage, LAMBDA(
+ allvoicesamples = strcat(allvoicesamples, " ", it.m_playersoundstr)
+ ));
+ allvoicesamples = strzone(substring(allvoicesamples, 1, -1));
+ }
+
+ .string _GetPlayerSoundSampleField(string type, bool voice)
+ {
+ GetPlayerSoundSampleField_notFound = false;
+ entity e = voice ? GetVoiceMessage(type) : GetPlayerSound(type);
+ if (e) return e.m_playersoundfld;
+ GetPlayerSoundSampleField_notFound = true;
+ return playersound_taunt.m_playersoundfld;
+ }
+
+ .string GetVoiceMessageSampleField(string type)
+ {
+ return _GetPlayerSoundSampleField(type, true);
+ }
+
+ void PrecachePlayerSounds(string f)
+ {
+ int fh = fopen(f, FILE_READ);
+ if (fh < 0)
+ {
+ LOG_WARNINGF("Player sound file not found: %s\n", f);
+ return;
+ }
+ for (string s; (s = fgets(fh)); )
+ {
+ int n = tokenize_console(s);
+ if (n != 3)
+ {
+ if (n != 0) LOG_WARNINGF("Invalid sound info line: %s\n", s);
+ continue;
+ }
+ string file = argv(1);
+ string variants = argv(2);
+ PrecacheGlobalSound(strcat(file, " ", variants));
+ }
+ fclose(fh);
+ }
+
+ #ifdef CSQC
+
+ .string GetPlayerSoundSampleField(string type)
+ {
+ return _GetPlayerSoundSampleField(type, false);
+ }
+
+ void ClearPlayerSounds(entity this)
+ {
+ FOREACH(PlayerSounds, true, LAMBDA(
+ .string fld = it.m_playersoundfld;
+ if (this.(fld))
+ {
+ strunzone(this.(fld));
+ this.(fld) = string_null;
+ }
+ ));
+ }
+
+ bool LoadPlayerSounds(entity this, string f, bool strict)
+ {
+ int fh = fopen(f, FILE_READ);
+ if (fh < 0)
+ {
+ if (strict) LOG_WARNINGF("Player sound file not found: %s\n", f);
+ return false;
+ }
+ for (string s; (s = fgets(fh)); )
+ {
+ int n = tokenize_console(s);
+ if (n != 3)
+ {
+ if (n != 0) LOG_WARNINGF("Invalid sound info line: %s\n", s);
+ continue;
+ }
+ string key = argv(0);
+ var.string field = GetPlayerSoundSampleField(key);
+ if (GetPlayerSoundSampleField_notFound) field = GetVoiceMessageSampleField(key);
+ if (GetPlayerSoundSampleField_notFound)
+ {
+ LOG_TRACEF("Invalid sound info field: %s\n", key);
+ continue;
+ }
+ string file = argv(1);
+ string variants = argv(2);
+ if (this.(field)) strunzone(this.(field));
+ this.(field) = strzone(strcat(file, " ", variants));
+ }
+ fclose(fh);
+ return true;
+ }
+
+ .string model_for_playersound;
+ .int skin_for_playersound;
+
+ bool autocvar_g_debug_defaultsounds;
+
+ void UpdatePlayerSounds(entity this)
+ {
+ if (this.model == this.model_for_playersound && this.skin == this.skin_for_playersound) return;
+ if (this.model_for_playersound) strunzone(this.model_for_playersound);
+ this.model_for_playersound = strzone(this.model);
+ this.skin_for_playersound = this.skin;
+ ClearPlayerSounds(this);
+ LoadPlayerSounds(this, "sound/player/default.sounds", true);
+ if (this.model == "null" || autocvar_g_debug_defaultsounds) return;
+ if (LoadPlayerSounds(this, get_model_datafilename(this.model, this.skin, "sounds"), false)) return;
+ LoadPlayerSounds(this, get_model_datafilename(this.model, 0, "sounds"), true);
+ }
+
+ #endif
+
+ #ifdef SVQC
+
+ void _GlobalSound(entity gs, entity ps, string sample, int chan, int voicetype, bool fake)
+ {
+ SELFPARAM();
+ if (gs == NULL && ps == NULL && sample == "") return;
+ float r = random();
+ if (sample != "") sample = GlobalSound_sample(sample, r);
+ switch (voicetype)
+ {
+ case VOICETYPE_LASTATTACKER_ONLY:
+ case VOICETYPE_LASTATTACKER:
+ {
+ if (!fake)
+ {
+ if (!this.pusher) break;
+ msg_entity = this.pusher;
+ if (IS_REAL_CLIENT(msg_entity))
+ {
+ float atten = (msg_entity.cvar_cl_voice_directional == 1) ? ATTEN_MIN : ATTEN_NONE;
+ if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten);
+ else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten);
+ else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten);
+ }
+ }
+ if (voicetype == VOICETYPE_LASTATTACKER_ONLY) break;
+ msg_entity = this;
+ if (IS_REAL_CLIENT(msg_entity))
+ {
+ if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASE, ATTEN_NONE);
+ else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASE, ATTEN_NONE);
+ else soundto(MSG_ONE, this, chan, sample, VOL_BASE, ATTEN_NONE);
+ }
+ break;
+ }
+ case VOICETYPE_TEAMRADIO:
+ {
+ #define X() \
+ do \
+ { \
+ float atten = (msg_entity.cvar_cl_voice_directional == 1) ? ATTEN_MIN : ATTEN_NONE; \
+ if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten); \
+ else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten); \
+ else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten); \
+ } \
+ while (0)
+
+ if (fake) { msg_entity = this; X(); }
+ else
+ {
+ FOR_EACH_REALCLIENT(msg_entity)
+ {
+ if (!teamplay || msg_entity.team == this.team) X();
+ }
+ }
+ #undef X
+ break;
+ }
+ case VOICETYPE_AUTOTAUNT:
+ case VOICETYPE_TAUNT:
+ {
+ if (voicetype == VOICETYPE_AUTOTAUNT) if (!sv_autotaunt) { break; }else {}
+ else if (IS_PLAYER(this) && this.deadflag == DEAD_NO) animdecide_setaction(this, ANIMACTION_TAUNT,
+ true);
+ if (!sv_taunt) break;
+ if (autocvar_sv_gentle) break;
+ float tauntrand = 0;
+ if (voicetype == VOICETYPE_AUTOTAUNT) tauntrand = random();
+ #define X() \
+ do \
+ { \
+ if (voicetype != VOICETYPE_AUTOTAUNT || tauntrand < msg_entity.cvar_cl_autotaunt) \
+ { \
+ float atten = (msg_entity.cvar_cl_voice_directional >= 1) \
+ ? bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, \
+ ATTEN_MAX) \
+ : ATTEN_NONE; \
+ if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten); \
+ else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten); \
+ else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten); \
+ } \
+ } \
+ while (0)
+ if (fake)
+ {
+ msg_entity = this;
+ X();
+ }
+ else
+ {
+ FOR_EACH_REALCLIENT(msg_entity)
+ {
+ X();
+ }
+ }
+ #undef X
+ break;
+ }
+ case VOICETYPE_PLAYERSOUND:
+ {
+ msg_entity = this;
+ if (fake)
+ {
+ if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASE, ATTEN_NORM);
+ else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASE, ATTEN_NORM);
+ else soundto(MSG_ONE, this, chan, sample, VOL_BASE, ATTEN_NORM);
+ }
+ else
+ {
+ if (gs) globalsound(MSG_ALL, this, gs, r, chan, VOL_BASE, ATTEN_NORM);
+ else if (ps) playersound(MSG_ALL, this, ps, r, chan, VOL_BASE, ATTEN_NORM);
+ else _sound(this, chan, sample, VOL_BASE, ATTEN_NORM);
+ }
+ break;
+ }
+ default:
+ {
+ backtrace("Invalid voice type!");
+ break;
+ }
+ }
+ }
+
+ #endif
+#endif
--- /dev/null
+#ifndef GLOBALSOUND_H
+#define GLOBALSOUND_H
+
+// player sounds, voice messages
+
+.string m_playersoundstr;
+..string m_playersoundfld;
+
+REGISTRY(PlayerSounds, BITS(8) - 1)
+#define PlayerSounds_from(i) _PlayerSounds_from(i, NULL)
+#define REGISTER_PLAYERSOUND(id) \
+ .string _playersound_##id; \
+ REGISTER(PlayerSounds, playersound, id, m_id, new(PlayerSound)) \
+ { \
+ make_pure(this); \
+ this.m_playersoundstr = #id; \
+ this.m_playersoundfld = _playersound_##id; \
+ }
+REGISTER_REGISTRY(PlayerSounds)
+REGISTRY_SORT(PlayerSounds)
+STATIC_INIT(PlayerSounds_renumber)
+{
+ FOREACH(PlayerSounds, true, LAMBDA(it.m_id = i));
+}
+REGISTRY_CHECK(PlayerSounds)
+
+// TODO implement fall and falling
+
+REGISTER_PLAYERSOUND(death)
+REGISTER_PLAYERSOUND(drown)
+REGISTER_PLAYERSOUND(fall)
+REGISTER_PLAYERSOUND(falling)
+REGISTER_PLAYERSOUND(gasp)
+REGISTER_PLAYERSOUND(jump)
+REGISTER_PLAYERSOUND(pain100)
+REGISTER_PLAYERSOUND(pain25)
+REGISTER_PLAYERSOUND(pain50)
+REGISTER_PLAYERSOUND(pain75)
+
+.bool instanceOfVoiceMessage;
+.int m_playersoundvt;
+#define REGISTER_VOICEMSG(id, vt) \
+ .string _playersound_##id; \
+ REGISTER(PlayerSounds, playersound, id, m_id, new(VoiceMessage)) \
+ { \
+ make_pure(this); \
+ this.instanceOfVoiceMessage = true; \
+ this.m_playersoundstr = #id; \
+ this.m_playersoundfld = _playersound_##id; \
+ this.m_playersoundvt = vt; \
+ }
+
+const int VOICETYPE_PLAYERSOUND = 10;
+const int VOICETYPE_TEAMRADIO = 11;
+const int VOICETYPE_LASTATTACKER = 12;
+const int VOICETYPE_LASTATTACKER_ONLY = 13;
+const int VOICETYPE_AUTOTAUNT = 14;
+const int VOICETYPE_TAUNT = 15;
+
+REGISTER_VOICEMSG(attack, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(attackinfive, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(coverme, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(defend, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(freelance, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(incoming, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(meet, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(needhelp, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(seenflag, VOICETYPE_TEAMRADIO)
+REGISTER_VOICEMSG(taunt, VOICETYPE_TAUNT)
+REGISTER_VOICEMSG(teamshoot, VOICETYPE_LASTATTACKER)
+
+// reserved sound names for the future (some models lack sounds for them):
+// _VOICEMSG(flagcarriertakingdamage)
+// _VOICEMSG(getflag)
+// reserved sound names for the future (ALL models lack sounds for them):
+// _VOICEMSG(affirmative)
+// _VOICEMSG(attacking)
+// _VOICEMSG(defending)
+// _VOICEMSG(roaming)
+// _VOICEMSG(onmyway)
+// _VOICEMSG(droppedflag)
+// _VOICEMSG(negative)
+// _VOICEMSG(seenenemy)
+
+.string m_globalsoundstr;
+REGISTRY(GlobalSounds, BITS(8) - 1)
+#define GlobalSounds_from(i) _GlobalSounds_from(i, NULL)
+#define REGISTER_GLOBALSOUND(id, str) \
+ REGISTER(GlobalSounds, GS, id, m_id, new(GlobalSound)) \
+ { \
+ make_pure(this); \
+ this.m_globalsoundstr = str; \
+ }
+REGISTER_REGISTRY(GlobalSounds)
+REGISTRY_SORT(GlobalSounds)
+STATIC_INIT(GlobalSounds_renumber)
+{
+ FOREACH(GlobalSounds, true, LAMBDA(it.m_id = i));
+}
+REGISTRY_CHECK(GlobalSounds)
+void PrecacheGlobalSound(string samplestring);
+PRECACHE(GlobalSounds)
+{
+ FOREACH(GlobalSounds, true, LAMBDA(PrecacheGlobalSound(it.m_globalsoundstr)));
+}
+
+REGISTER_GLOBALSOUND(STEP, "misc/footstep0 6")
+REGISTER_GLOBALSOUND(STEP_METAL, "misc/metalfootstep0 6")
+REGISTER_GLOBALSOUND(FALL, "misc/hitground 4")
+REGISTER_GLOBALSOUND(FALL_METAL, "misc/metalhitground 4")
+
+bool GetPlayerSoundSampleField_notFound;
+void PrecachePlayerSounds(string f);
+#ifdef CSQC
+ .string GetVoiceMessageSampleField(string type);
+ .string GetPlayerSoundSampleField(string type);
+ void ClearPlayerSounds(entity this);
+ float LoadPlayerSounds(entity this, string f, bool strict);
+ void UpdatePlayerSounds(entity this);
+#endif
+
+#ifdef SVQC
+
+ void _GlobalSound(entity gs, entity ps, string sample, float chan, float voicetype, bool fake);
+ #define GlobalSound(def, chan, voicetype) _GlobalSound(def, NULL, string_null, chan, voicetype, false)
+ #define GlobalSound_string(def, chan, voicetype) _GlobalSound(NULL, NULL, def, chan, voicetype, false)
+ #define PlayerSound(def, chan, voicetype) _GlobalSound(NULL, def, string_null, chan, voicetype, false)
+ #define VoiceMessage(def, msg) \
+ do \
+ { \
+ entity VM = def; \
+ int voicetype = VM.m_playersoundvt; \
+ bool ownteam = (voicetype == VOICETYPE_TEAMRADIO); \
+ int flood = Say(this, ownteam, world, msg, true); \
+ bool fake; \
+ if (IS_SPEC(this) || IS_OBSERVER(this) || flood < 0) fake = true; \
+ else if (flood > 0) fake = false; \
+ else break; \
+ _GlobalSound(NULL, VM, string_null, CH_VOICE, voicetype, fake); \
+ } \
+ while (0)
+
+#endif
+
+#endif
--- /dev/null
+#include "ent_cs.qh"
+
+// #define PROP(public, fld, sv, cl)
+#define ENTCS_NETPROPS(PROP) \
+ PROP(true, sv_entnum, \
+ { WriteByte(MSG_ENTITY, etof(player) - 1); }, \
+ { this.sv_entnum = ReadByte(); }) \
+ \
+ PROP(false, origin, \
+ { WriteShort(MSG_ENTITY, this.origin.x); WriteShort(MSG_ENTITY, this.origin.y); \
+ WriteShort(MSG_ENTITY, this.origin.z); }, \
+ { this.has_sv_origin = true; vector v; v.x = ReadShort(); v.y = ReadShort(); v.z = ReadShort(); setorigin(this, v); }) \
+ \
+ PROP(false, angles_y, \
+ { WriteByte(MSG_ENTITY, this.angles.y / 360 * 256); }, \
+ { vector v = '0 0 0'; v.y = ReadByte() / 256 * 360; this.angles = v; }) \
+ \
+ PROP(false, health, \
+ { WriteByte(MSG_ENTITY, this.health / 10); /* FIXME: use a better scale? */ }, \
+ { this.healthvalue = ReadByte() * 10; }) \
+ \
+ PROP(false, armorvalue, \
+ { WriteByte(MSG_ENTITY, this.armorvalue / 10); /* FIXME: use a better scale? */ }, \
+ { this.armorvalue = ReadByte() * 10; }) \
+ \
+ PROP(true, netname, \
+ { WriteString(MSG_ENTITY, this.netname); }, \
+ { if (this.netname) strunzone(this.netname); this.netname = strzone(ReadString()); }) \
+ \
+ PROP(true, model, \
+ { WriteString(MSG_ENTITY, this.model); }, \
+ { if (this.model) strunzone(this.model); this.model = strzone(ReadString()); }) \
+ \
+ PROP(true, skin, \
+ { WriteByte(MSG_ENTITY, this.skin); }, \
+ { this.skin = ReadByte(); }) \
+ \
+ /**/
+
+#ifdef SVQC
+
+ int ENTCS_PUBLICMASK = 0;
+ STATIC_INIT(ENTCS_PUBLICMASK)
+ {
+ int i = 1;
+ #define X(public, fld, sv, cl) { if (public) ENTCS_PUBLICMASK |= BIT(i); } i += 1;
+ ENTCS_NETPROPS(X);
+ #undef X
+ if (i >= BITS(16 - 1)) LOG_FATAL("Exceeded ENTCS_NETPROPS limit");
+ }
+
+ bool entcs_send(entity this, entity to, int sf)
+ {
+ entity player = this.owner;
+ sf |= 1;
+ if (IS_PLAYER(to) || to.caplayer) // unless spectating,
+ {
+ bool same_team = (to == player) || (teamplay && player.team == to.team);
+ if (!same_team && !radar_showennemies) sf &= ENTCS_PUBLICMASK; // no private updates
+ }
+ sf |= this.m_forceupdate;
+ this.m_forceupdate = 0;
+ bool valid =
+ IS_PLAYER(player) // player must be active
+ && player.deadflag == DEAD_NO // player must be alive
+ || player == to // player is self
+ ;
+ if (!valid) sf = 0;
+ WriteHeader(MSG_ENTITY, ENT_CLIENT_ENTCS);
+ WriteShort(MSG_ENTITY, sf);
+ int i = 1;
+ #define X(public, fld, sv, cl) { if (sf & BIT(i)) sv; } i += 1;
+ ENTCS_NETPROPS(X);
+ #undef X
+ return true;
+ }
+
+ void entcs_think()
+ {
+ SELFPARAM();
+ this.nextthink = time + 0.033333333333; // TODO: increase this to like 0.15 once the client can do smoothing
+ entity o = this.owner;
+ int i = 1;
+ #define X(public, fld, sv, cl) \
+ if (o.fld != this.fld) \
+ { \
+ this.fld = o.fld; \
+ this.SendFlags |= BIT(i); \
+ } \
+ i += 1;
+ ENTCS_NETPROPS(X);
+ #undef X
+ }
+
+ void entcs_attach(entity player)
+ {
+ entity e = player.entcs = new(entcs_sender);
+ make_pure(e);
+ e.owner = player;
+ e.think = entcs_think;
+ e.nextthink = time;
+ Net_LinkEntity(e, false, 0, entcs_send);
+ }
+
+ void entcs_detach(entity player)
+ {
+ if (!player.entcs) return;
+ remove(player.entcs);
+ player.entcs = NULL;
+ }
+
+#endif
+
+#ifdef CSQC
+
+ void Ent_RemoveEntCS()
+ {
+ SELFPARAM();
+ entcs_receiver(this.sv_entnum, NULL);
+ }
+
+ void entcs_think()
+ {
+ SELFPARAM();
+ this.nextthink = time;
+ entity e = CSQCModel_server2csqc(this.sv_entnum + 1);
+ bool exists = e != NULL;
+ if (exists)
+ {
+ this.has_origin = true;
+ this.origin = e.origin;
+ // `cl_forceplayermodels 1` sounds will be wrong until the player has been in the PVS, but so be it
+ if (this.model != e.model)
+ {
+ if (this.model) strunzone(this.model);
+ this.model = strzone(e.model);
+ }
+ }
+ else
+ {
+ this.has_origin = this.has_sv_origin;
+ }
+ }
+
+ NET_HANDLE(ENT_CLIENT_ENTCS, bool isnew)
+ {
+ if (isnew)
+ {
+ make_pure(this);
+ this.classname = "entcs_receiver";
+ this.entremove = Ent_RemoveEntCS;
+ this.think = entcs_think;
+ this.nextthink = time;
+ }
+ InterpolateOrigin_Undo(this);
+ int sf = ReadShort();
+ this.has_sv_origin = false;
+ this.m_entcs_private = boolean(sf & 1);
+ int i = 1;
+ #define X(public, fld, sv, cl) { if (sf & BIT(i)) cl; } i += 1;
+ ENTCS_NETPROPS(X);
+ #undef X
+ entcs_receiver(this.sv_entnum, this);
+ this.iflags |= IFLAG_ORIGIN;
+ InterpolateOrigin_Note(this);
+ return true;
+ }
+
+#endif
--- /dev/null
+#ifndef ENT_CS_H
+#define ENT_CS_H
+
+REGISTER_NET_LINKED(ENT_CLIENT_ENTCS)
+
+/** True when private information such as origin is available */
+.bool m_entcs_private;
+/** True when origin is available */
+.bool has_origin;
+/** True when a recent server sent origin has been received */
+.bool has_sv_origin;
+
+#ifdef SVQC
+/**
+ * The point of these entities is to avoid the problems
+ * with clientprediction.
+ * If you add SendEntity to players, the engine will not
+ * do any prediction anymore, and you'd have to write the whole
+ * prediction code in CSQC, you want that? :P
+ * Data can depend on gamemode. For now, it serves as GPS entities
+ * in onslaught... YAY ;)
+ */
+
+.entity entcs;
+
+bool entcs_send(entity this, entity to, int sf);
+
+void entcs_think();
+
+void entcs_attach(entity e);
+
+void entcs_detach(entity e);
+
+.int m_forceupdate;
+
+/** Force an origin update, for player sounds */
+#define entcs_force_origin(e) ((e).entcs.m_forceupdate = BIT(2))
+
+#endif
+
+#ifdef CSQC
+
+AL_declare(_entcs);
+STATIC_INIT(_entcs)
+{
+ AL_init(_entcs, 255, NULL, e); // 255 is the engine limit on maxclients
+}
+#define entcs_receiver(...) EVAL(OVERLOAD(entcs_receiver, __VA_ARGS__))
+#define entcs_receiver_1(i) AL_gete(_entcs, i)
+#define entcs_receiver_2(i, v) AL_sete(_entcs, i, v)
+#define entcs_is_self(e) ((e).sv_entnum + 1 == player_localentnum)
+
+#endif
+
+#endif
GameLogEcho(s);
}
-void ball_restart()
-{SELFPARAM();
- if(self.owner)
- DropBall(self, self.owner.origin, '0 0 0');
+void ball_restart(entity this)
+{
+ if(this.owner)
+ DropBall(this, this.owner.origin, '0 0 0');
ResetBall();
}
W_SetupProjVelocity_Basic(missile, autocvar_g_balance_nexball_secondary_speed, 0);
missile.angles = vectoangles(missile.velocity);
missile.touch = W_Nexball_Touch;
- missile.think = SUB_Remove;
+ missile.think = SUB_Remove_self;
missile.nextthink = time + autocvar_g_balance_nexball_secondary_lifetime; //FIXME: use a distance instead?
missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
}
}
-void ons_CaptureShield_Reset()
-{SELFPARAM();
- self.colormap = self.enemy.colormap;
- self.team = self.enemy.team;
+void ons_CaptureShield_Reset(entity this)
+{
+ this.colormap = this.enemy.colormap;
+ this.team = this.enemy.team;
}
void ons_CaptureShield_Spawn(entity generator, bool is_generator)
CSQCMODEL_AUTOUPDATE(self);
}
-void ons_ControlPoint_Reset()
-{SELFPARAM();
- if(self.goalentity)
- remove(self.goalentity);
-
- self.goalentity = world;
- self.team = 0;
- self.colormap = 1024;
- self.iscaptured = false;
- self.islinked = false;
- self.isshielded = true;
- self.think = ons_ControlPoint_Think;
- self.ons_toucher = world;
- self.nextthink = time + ONS_CP_THINKRATE;
- setmodel_fixsize(self, MDL_ONS_CP_PAD1);
-
- WaypointSprite_UpdateMaxHealth(self.sprite, 0);
- WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY);
+void ons_ControlPoint_Reset(entity this)
+{
+ if(this.goalentity)
+ remove(this.goalentity);
+
+ this.goalentity = world;
+ this.team = 0;
+ this.colormap = 1024;
+ this.iscaptured = false;
+ this.islinked = false;
+ this.isshielded = true;
+ this.think = ons_ControlPoint_Think;
+ this.ons_toucher = world;
+ this.nextthink = time + ONS_CP_THINKRATE;
+ setmodel_fixsize(this, MDL_ONS_CP_PAD1);
+
+ WaypointSprite_UpdateMaxHealth(this.sprite, 0);
+ WaypointSprite_UpdateRule(this.sprite,this.team,SPRITERULE_TEAMPLAY);
onslaught_updatelinks();
- activator = self;
+ activator = this;
SUB_UseTargets(); // to reset the structures, playerspawns etc.
- CSQCMODEL_AUTOUPDATE(self);
+ CSQCMODEL_AUTOUPDATE(this);
}
void ons_DelayedControlPoint_Setup()
}
}
-void ons_GeneratorReset()
-{SELFPARAM();
- self.team = self.team_saved;
- self.lasthealth = self.max_health = self.health = autocvar_g_onslaught_gen_health;
- self.takedamage = DAMAGE_AIM;
- self.bot_attack = true;
- self.iscaptured = true;
- self.islinked = true;
- self.isshielded = true;
- self.event_damage = ons_GeneratorDamage;
- self.think = ons_GeneratorThink;
- self.nextthink = time + GEN_THINKRATE;
-
- Net_LinkEntity(self, false, 0, generator_send);
-
- self.SendFlags = GSF_SETUP; // just incase
- self.SendFlags |= GSF_STATUS;
-
- WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
- WaypointSprite_UpdateHealth(self.sprite, self.health);
- WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY);
+void ons_GeneratorReset(entity this)
+{
+ this.team = this.team_saved;
+ this.lasthealth = this.max_health = this.health = autocvar_g_onslaught_gen_health;
+ this.takedamage = DAMAGE_AIM;
+ this.bot_attack = true;
+ this.iscaptured = true;
+ this.islinked = true;
+ this.isshielded = true;
+ this.event_damage = ons_GeneratorDamage;
+ this.think = ons_GeneratorThink;
+ this.nextthink = time + GEN_THINKRATE;
+
+ Net_LinkEntity(this, false, 0, generator_send);
+
+ this.SendFlags = GSF_SETUP; // just incase
+ this.SendFlags |= GSF_STATUS;
+
+ WaypointSprite_UpdateMaxHealth(this.sprite, this.max_health);
+ WaypointSprite_UpdateHealth(this.sprite, this.health);
+ WaypointSprite_UpdateRule(this.sprite,this.team,SPRITERULE_TEAMPLAY);
onslaught_updatelinks();
}
REGISTRY(Items, BITS(5))
#define Items_from(i) _Items_from(i, NULL)
-REGISTER_REGISTRY(RegisterItems)
+REGISTER_REGISTRY(Items)
/** If you register a new item, make sure to add it to all.inc */
-#define REGISTER_ITEM(id, class) REGISTER(RegisterItems, ITEM, Items, id, m_id, NEW(class))
+#define REGISTER_ITEM(id, class) REGISTER(Items, ITEM, id, m_id, NEW(class))
-REGISTRY_SORT(Items, 0)
+REGISTRY_SORT(Items)
REGISTRY_CHECK(Items)
STATIC_INIT(Items) { FOREACH(Items, true, LAMBDA(it.m_id = i)); }
{
WriteHeader(MSG_ENTITY, ENT_CLIENT_INVENTORY);
entity e = self.owner;
- if (/*IS_SPEC(e)*/ (e.classname == "spectator")) e = e.enemy;
+ if (IS_SPEC(e)) e = e.enemy;
Inventory data = e.inventory;
Inventory_Write(data);
return true;
#if defined(CSQC)
#include "../client/defs.qh"
#include "util.qh"
- #include "buffs/all.qh"
#include "weapons/all.qh"
#include "mapinfo.qh"
#elif defined(MENUQC)
#elif defined(SVQC)
#include "util.qh"
- #include "buffs/all.qh"
#include "monsters/all.qh"
#include "mapinfo.qh"
#endif
{
MapInfo_Map_flags |= MAPINFO_FLAG_NOAUTOMAPLIST;
}
+ else if(t == "gameversion_min")
+ {
+ if (cvar("gameversion") < stof(s))
+ MapInfo_Map_flags |= MAPINFO_FLAG_NOAUTOMAPLIST;
+ }
else if(t == "type")
{
t = car(s); s = cdr(s);
REGISTRY(Gametypes, BITS(4))
#define Gametypes_from(i) _Gametypes_from(i, NULL)
-REGISTER_REGISTRY(RegisterGametypes)
+REGISTER_REGISTRY(Gametypes)
REGISTRY_CHECK(Gametypes)
int MAPINFO_TYPE_ALL;
#define REGISTER_GAMETYPE(hname, sname, g_name, NAME, gteamplay, mutators, defaults, gdescription) \
int MAPINFO_TYPE_##NAME; \
bool NAME##_mapinfo(string k, string v) { return = false; } \
- REGISTER(RegisterGametypes, MAPINFO_TYPE, Gametypes, g_name, m_id, \
+ REGISTER(Gametypes, MAPINFO_TYPE, g_name, m_id, \
NEW(Gametype, hname, #sname, #g_name, gteamplay, #sname " " mutators, defaults, gdescription) \
) { \
/* same as `1 << m_id` */ \
deactivate_minigame();
}
-vector ReadVector2D() { vector v; v_x = ReadCoord(); v_y = ReadCoord(); v_z = 0; return v; }
-vector ReadVector() { vector v; v_x = ReadCoord(); v_y = ReadCoord(); v_z = ReadCoord(); return v; }
string() ReadString_Raw = #366;
string ReadString_Zoned() { return strzone(ReadString_Raw()); }
#define ReadString ReadString_Zoned
while( (entityvar = findentity(entityvar,owner,active_minigame)) )
-REGISTRY(Minigames, BITS(3))
+REGISTRY(Minigames, BITS(4))
#define Minigames_from(i) _Minigames_from(i, NULL)
-REGISTER_REGISTRY(RegisterMinigames)
+REGISTER_REGISTRY(Minigames)
REGISTRY_CHECK(Minigames)
#define REGISTER_MINIGAME(name,nicename) \
- REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, new(minigame_descriptor)); \
+ REGISTER(Minigames, MINIGAME_##name, m_id, new(minigame_descriptor)); \
void name##_hud_board(vector, vector); \
void name##_hud_status(vector, vector); \
int name##_client_event(entity, string, ...); \
- REGISTER_INIT_POST(MINIGAME, name) { \
+ REGISTER_INIT_POST(MINIGAME_##name) { \
make_pure(this); \
this.netname = strzone(strtolower(#name)); \
this.message = nicename; \
this.minigame_hud_status = name##_hud_status; \
this.minigame_event = name##_client_event; \
} \
- REGISTER_INIT(MINIGAME, name)
+ REGISTER_INIT(MINIGAME_##name)
#endif
// Whether the minigame menu panel is open
bool HUD_MinigameMenu_IsOpened()
{
- return !!HUD_MinigameMenu_entries;
+ return HUD_MinigameMenu_entries != NULL;
}
// Close the minigame menu panel
#include "ps.qc"
#include "pp.qc"
#include "snake.qc"
+#include "bd.qc"
/**
* Set up automatic entity read/write functionality
--- /dev/null
+REGISTER_MINIGAME(bd, "Bulldozer");
+
+const int BD_TURN_MOVE = 0x0100; // player must move the bulldozer
+const int BD_TURN_WIN = 0x0200; // victory
+const int BD_TURN_LOSS = 0x0400; // they did it?!
+const int BD_TURN_EDIT = 0x0800; // editing mode
+const int BD_TURN_TYPE = 0x0f00; // turn type mask
+
+const int BD_SF_PLAYERMOVES = MINIG_SF_CUSTOM;
+
+// 240 tiles...
+const int BD_LET_CNT = 20;
+const int BD_NUM_CNT = 20;
+
+const int BD_TILE_SIZE = 20;
+
+const int BD_TEAMS = 1;
+
+.vector bd_dir;
+
+.int bd_moves;
+
+.string bd_levelname;
+.string bd_nextlevel;
+
+#ifdef SVQC
+.bool bd_canedit;
+#endif
+
+.int bd_tiletype;
+const int BD_TILE_DOZER = 1;
+const int BD_TILE_TARGET = 2;
+const int BD_TILE_BOULDER = 3;
+const int BD_TILE_BRICK1 = 4;
+const int BD_TILE_BRICK2 = 5;
+const int BD_TILE_BRICK3 = 6;
+const int BD_TILE_BRICK4 = 7;
+const int BD_TILE_BRICK5 = 8;
+const int BD_TILE_BRICK6 = 9;
+const int BD_TILE_BRICK7 = 10;
+const int BD_TILE_BRICK8 = 11;
+const int BD_TILE_LAST = 11;
+
+string autocvar_sv_minigames_bulldozer_startlevel = "level1";
+
+// find same game piece given its tile name
+entity bd_find_piece(entity minig, string tile, bool check_target)
+{
+ entity e = world;
+ while ( ( e = findentity(e,owner,minig) ) )
+ if ( e.classname == "minigame_board_piece" && e.netname == tile && ((check_target) ? e.bd_tiletype == BD_TILE_TARGET : e.bd_tiletype != BD_TILE_TARGET) )
+ return e;
+ return world;
+}
+
+// check if the tile name is valid (15x15 grid)
+bool bd_valid_tile(string tile)
+{
+ if ( !tile )
+ return false;
+ int number = minigame_tile_number(tile);
+ int letter = minigame_tile_letter(tile);
+ return 0 <= number && number < BD_NUM_CNT && 0 <= letter && letter < BD_LET_CNT;
+}
+
+entity bd_find_dozer(entity minig)
+{
+ entity e = world;
+ while ( ( e = findentity(e,owner,minig) ) )
+ if ( e.classname == "minigame_board_piece" && e.bd_tiletype == BD_TILE_DOZER )
+ return e;
+ return world;
+}
+
+void bd_check_winner(entity minig)
+{
+ int total = 0, valid = 0;
+ entity e = world;
+ while ( ( e = findentity(e,owner,minig) ) )
+ if ( e.classname == "minigame_board_piece" && e.bd_tiletype == BD_TILE_TARGET )
+ {
+ ++total;
+ if(bd_find_piece(minig, e.netname, false).bd_tiletype == BD_TILE_BOULDER)
+ ++valid;
+ }
+
+ if(valid >= total)
+ {
+ minig.minigame_flags = BD_TURN_WIN;
+ minigame_server_sendflags(minig,MINIG_SF_UPDATE);
+ }
+}
+
+bool bd_canfill(int ttype)
+{
+ switch(ttype)
+ {
+ case BD_TILE_BRICK8:
+ case BD_TILE_BRICK7:
+ case BD_TILE_BRICK6:
+ case BD_TILE_BRICK5:
+ case BD_TILE_BRICK4:
+ case BD_TILE_BRICK3:
+ case BD_TILE_BRICK2:
+ case BD_TILE_BRICK1: return true;
+ }
+
+ return false;
+}
+
+bool bd_move_dozer(entity minigame, entity dozer)
+{
+ if(!dozer.bd_dir_x && !dozer.bd_dir_y)
+ return false; // nope!
+
+ int myx = minigame_tile_letter(dozer.netname);
+ int myy = minigame_tile_number(dozer.netname);
+
+ myx += dozer.bd_dir_x;
+ myy += dozer.bd_dir_y;
+
+ string newpos = minigame_tile_buildname(myx, myy);
+ entity hit = bd_find_piece(minigame, newpos, false);
+
+ if(!bd_valid_tile(newpos))
+ return false;
+
+ if(hit)
+ switch(hit.bd_tiletype)
+ {
+ case BD_TILE_DOZER: // wtf, but let's do this incase
+ case BD_TILE_BRICK8:
+ case BD_TILE_BRICK7:
+ case BD_TILE_BRICK6:
+ case BD_TILE_BRICK5:
+ case BD_TILE_BRICK4:
+ case BD_TILE_BRICK3:
+ case BD_TILE_BRICK2:
+ case BD_TILE_BRICK1: return false;
+ case BD_TILE_BOULDER:
+ {
+ string testpos;
+ int tx = minigame_tile_letter(hit.netname);
+ int ty = minigame_tile_number(hit.netname);
+
+ tx += dozer.bd_dir_x;
+ ty += dozer.bd_dir_y;
+
+ testpos = minigame_tile_buildname(tx, ty);
+ entity testhit = bd_find_piece(minigame, testpos, false);
+
+ if(!bd_valid_tile(testpos) || testhit)
+ return false;
+
+ if(hit.netname) { strunzone(hit.netname); }
+ hit.netname = strzone(testpos);
+ minigame_server_sendflags(hit,MINIG_SF_UPDATE);
+ break;
+ }
+ }
+
+ if(dozer.netname) { strunzone(dozer.netname); }
+ dozer.netname = strzone(newpos);
+
+ return true;
+}
+
+// make a move
+void bd_move(entity minigame, entity player, string dir)
+{
+ if ( minigame.minigame_flags & BD_TURN_MOVE )
+ if ( dir )
+ {
+ //if ( bd_valid_tile(pos) )
+ //if ( bd_find_piece(minigame, pos, false) )
+ {
+ entity dozer = bd_find_dozer(minigame);
+ if(!dozer)
+ {
+ LOG_INFO("Dozer wasn't found!\n");
+ return; // should not happen... TODO: end match?
+ }
+
+ int dxs = 0, dys = 0;
+ string thedir = strtolower(dir);
+ if(thedir == "up" || thedir == "u") { dxs = 0; dys = 1; }
+ if(thedir == "down" || thedir == "dn" || thedir == "d") { dxs = 0; dys = -1; }
+ if(thedir == "left" || thedir == "lt" || thedir == "l") { dxs = -1; dys = 0; }
+ if(thedir == "right" || thedir == "rt" || thedir == "r") { dxs = 1; dys = 0; }
+
+ int dx = bound(-1, dxs, 1);
+ int dy = bound(-1, dys, 1);
+
+ dozer.bd_dir_x = dx;
+ dozer.bd_dir_y = dy;
+ dozer.bd_dir_z = 0;
+
+ if(bd_move_dozer(minigame, dozer))
+ player.bd_moves++;
+
+ bd_check_winner(minigame);
+
+ minigame_server_sendflags(dozer,MINIG_SF_UPDATE); // update anyway
+ minigame_server_sendflags(player,BD_SF_PLAYERMOVES);
+ minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
+ }
+ }
+}
+
+// editor
+void bd_editor_place(entity minigame, entity player, string pos, int thetile, string thedir)
+{
+ if ( minigame.minigame_flags & BD_TURN_EDIT )
+ if ( pos && thetile )
+ {
+ if ( bd_valid_tile(pos) )
+ {
+ entity found_piece = bd_find_piece(minigame, pos, false);
+ entity targ = bd_find_piece(minigame, pos, true);
+
+ if(found_piece.bd_tiletype == BD_TILE_DOZER && thedir != "")
+ {
+ int dxs = 0, dys = 0;
+ string newdir = strtolower(thedir);
+ if(newdir == "up" || newdir == "u") { dxs = 0; dys = 1; }
+ if(newdir == "down" || newdir == "dn" || newdir == "d") { dxs = 0; dys = -1; }
+ if(newdir == "left" || newdir == "lt" || newdir == "l") { dxs = -1; dys = 0; }
+ if(newdir == "right" || newdir == "rt" || newdir == "r") { dxs = 1; dys = 0; }
+
+ int dx = bound(-1, dxs, 1);
+ int dy = bound(-1, dys, 1);
+
+ found_piece.bd_dir_x = dx;
+ found_piece.bd_dir_y = dy;
+ found_piece.bd_dir_z = 0;
+ minigame_server_sendflags(found_piece,MINIG_SF_UPDATE); // update anyway
+ return;
+ }
+
+ entity dozer = bd_find_dozer(minigame);
+ if(dozer && thetile == BD_TILE_DOZER && pos != dozer.netname)
+ return; // nice try
+
+ if(found_piece || (targ && thetile != BD_TILE_BOULDER))
+ {
+ entity piece = bd_find_piece(minigame, pos, false);
+ if(!piece) piece = bd_find_piece(minigame, pos, true);
+ if(!piece)
+ return; // how?!
+
+ if(piece.netname) { strunzone(piece.netname); }
+ remove(piece);
+ minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
+ return;
+ }
+
+ entity piece = msle_spawn(minigame,"minigame_board_piece");
+ piece.team = 1;
+ piece.netname = strzone(pos);
+ piece.bd_tiletype = thetile;
+ piece.bd_dir = '0 -1 0';
+ minigame_server_sendflags(piece,MINIG_SF_UPDATE);
+
+ minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
+ }
+ }
+}
+
+void bd_do_move(entity minigame, entity player, string dir, string thetile, string thedir)
+{
+ if(minigame.minigame_flags & BD_TURN_MOVE)
+ bd_move(minigame, player, dir);
+
+ if(minigame.minigame_flags & BD_TURN_EDIT)
+ bd_editor_place(minigame, player, dir, stof(thetile), thedir);
+}
+
+void bd_fill_recurse(entity minigame, entity player, int thetype, int letter, int number)
+{
+ string pos = minigame_tile_buildname(letter,number);
+ if(!bd_valid_tile(pos))
+ return;
+ if(bd_find_piece(minigame, pos, false) || bd_find_piece(minigame, pos, true))
+ return;
+
+ bd_editor_place(minigame, player, pos, thetype, "");
+
+ bd_fill_recurse(minigame, player, thetype, letter - 1, number);
+ bd_fill_recurse(minigame, player, thetype, letter + 1, number);
+ bd_fill_recurse(minigame, player, thetype, letter, number - 1);
+ bd_fill_recurse(minigame, player, thetype, letter, number + 1);
+}
+
+void bd_unfill_recurse(entity minigame, entity player, int thetype, int letter, int number)
+{
+ string pos = minigame_tile_buildname(letter,number);
+ if(!bd_valid_tile(pos))
+ return;
+
+ entity targ = bd_find_piece(minigame, pos, true);
+ entity piece = bd_find_piece(minigame, pos, false);
+
+ if(targ && thetype == targ.bd_tiletype)
+ {
+ if(targ.netname) { strunzone(targ.netname); }
+ remove(targ);
+ }
+ else if(piece && thetype == piece.bd_tiletype)
+ {
+ if(piece.netname) { strunzone(piece.netname); }
+ remove(piece);
+ }
+ else return;
+
+ bd_unfill_recurse(minigame, player, thetype, letter - 1, number);
+ bd_unfill_recurse(minigame, player, thetype, letter + 1, number);
+ bd_unfill_recurse(minigame, player, thetype, letter, number - 1);
+ bd_unfill_recurse(minigame, player, thetype, letter, number + 1);
+}
+
+void bd_do_fill(entity minigame, entity player, string dir, string thetile)
+{
+ if(minigame.minigame_flags & BD_TURN_EDIT)
+ {
+ int thetype = stof(thetile);
+
+ entity targ = bd_find_piece(minigame, dir, true);
+ entity piece = bd_find_piece(minigame, dir, false);
+
+ if(!bd_canfill(thetype) || (piece || targ))
+ {
+ int killtype = 0;
+
+ if(targ) { killtype = targ.bd_tiletype; }
+ if(piece) { killtype = piece.bd_tiletype; }
+
+ if(killtype)
+ {
+ int letter = minigame_tile_letter(dir);
+ int number = minigame_tile_number(dir);
+ bd_unfill_recurse(minigame, player, killtype, letter, number);
+ }
+
+ return;
+ }
+
+ int letter = minigame_tile_letter(dir);
+ int number = minigame_tile_number(dir);
+
+ bd_fill_recurse(minigame, player, thetype, letter, number);
+ }
+}
+
+void bd_reset_moves(entity minigame)
+{
+ entity e;
+#ifdef SVQC
+ for(e = minigame.minigame_players; e; e = e.list_next)
+#elif defined(CSQC)
+ e = world;
+ while( (e = findentity(e,owner,minigame)) )
+ if ( e.classname == "minigame_player" )
+#endif
+ {
+ e.bd_moves = 0;
+ minigame_server_sendflags(e,BD_SF_PLAYERMOVES);
+ }
+}
+
+void bd_load_level(entity minigame);
+void bd_setup_pieces(entity minigame)
+{
+ entity e = world;
+ while( (e = findentity(e, owner, minigame)) )
+ if(e.classname == "minigame_board_piece")
+ {
+ if(e.netname) { strunzone(e.netname); }
+ remove(e);
+ }
+
+ bd_load_level(minigame);
+}
+
+void bd_do_next_match(entity minigame, entity player)
+{
+ minigame.minigame_flags = BD_TURN_MOVE;
+ minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
+
+ if(minigame.bd_nextlevel && minigame.bd_nextlevel != "")
+ {
+ if(minigame.bd_levelname) { strunzone(minigame.bd_levelname); }
+ minigame.bd_levelname = strzone(minigame.bd_nextlevel);
+ }
+
+ bd_setup_pieces(minigame);
+
+ bd_reset_moves(minigame);
+}
+
+void bd_set_next_match(entity minigame, string next)
+{
+ if(minigame.bd_nextlevel) { strunzone(minigame.bd_nextlevel); }
+ minigame.bd_nextlevel = strzone(next);
+}
+
+void bd_next_match(entity minigame, entity player, string next)
+{
+ if(minigame.minigame_flags & BD_TURN_WIN)
+ bd_do_next_match(minigame, player);
+ if(minigame.minigame_flags & BD_TURN_EDIT)
+ bd_set_next_match(minigame, next);
+}
+
+// request a new match
+void bd_restart_match(entity minigame, entity player)
+{
+ minigame.minigame_flags = BD_TURN_MOVE;
+ minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
+
+ bd_setup_pieces(minigame);
+
+ bd_reset_moves(minigame);
+}
+
+void bd_activate_editor(entity minigame, entity player)
+{
+#ifdef SVQC
+ if(!player.minigame_players.bd_canedit)
+ {
+ sprint(player.minigame_players, "You're not allowed to edit levels, sorry!\n");
+ return;
+ }
+#endif
+
+ minigame.minigame_flags = BD_TURN_EDIT;
+ minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
+
+ bd_reset_moves(minigame);
+
+ bd_setup_pieces(minigame);
+}
+
+string bd_save_piece(entity minigame, entity e)
+{
+ string bd_string = "";
+
+ bd_string = strcat(bd_string, "\"", e.netname, "\" ");
+ bd_string = strcat(bd_string, ftos(e.bd_tiletype), " ");
+ bd_string = strcat(bd_string, sprintf("\"%.9v\"", e.bd_dir));
+
+ return bd_string;
+}
+
+void bd_set_nextlevel(entity minigame, string s)
+{
+ tokenize_console(s);
+
+ if(minigame.bd_nextlevel) { strunzone(minigame.bd_nextlevel); }
+ minigame.bd_nextlevel = strzone(argv(2));
+}
+
+entity bd_load_piece(entity minigame, string s)
+{
+ // separate pieces between the ; symbols
+ string bd_string = s;
+
+ tokenize_console(bd_string);
+
+ entity e = msle_spawn(minigame,"minigame_board_piece");
+ e.team = 1;
+ e.bd_dir = '0 -1 0';
+
+ int argv_num = 0;
+ e.netname = strzone(argv(argv_num)); ++argv_num;
+ e.bd_tiletype = stof(argv(argv_num)); ++argv_num;
+ e.bd_dir = stov(argv(argv_num)); ++argv_num;
+
+ minigame_server_sendflags(e,MINIG_SF_ALL);
+
+ return e;
+}
+
+bool bd_save_level(entity minigame)
+{
+ if(minigame.bd_levelname && minigame.bd_levelname != "")
+ {
+ int target_count = 0, boulder_count = 0;
+ entity piece = world;
+ while((piece = findentity(piece,owner,minigame)))
+ if(piece.classname == "minigame_board_piece")
+ if(piece.bd_tiletype == BD_TILE_BOULDER)
+ ++boulder_count;
+ else if(piece.bd_tiletype == BD_TILE_TARGET)
+ ++target_count;
+
+ if(boulder_count != target_count)
+ {
+ LOG_INFO("Not enough targets or boulders, fix your level!\n");
+ return false;
+ }
+
+ // saves all objects to the database file
+ string file_name;
+ float file_get;
+
+ file_name = strcat("minigames/bulldozer/storage_", minigame.bd_levelname, ".txt");
+ file_get = fopen(file_name, FILE_WRITE);
+ fputs(file_get, strcat("// bulldozer storage \"", minigame.bd_levelname, "\" last updated ", strftime(true, "%d-%m-%Y %H:%M:%S"), "\n"));
+
+ if(minigame.bd_nextlevel && minigame.bd_nextlevel != "" && fexists(strcat("minigames/bulldozer/storage_", minigame.bd_nextlevel, ".txt")))
+ fputs(file_get, strcat("nextlevel = \"", minigame.bd_nextlevel, "\"\n"));
+
+ entity e = world;
+ while ( ( e = findentity(e,owner,minigame) ) )
+ if ( e.classname == "minigame_board_piece" )
+ {
+ // use a line of text for each object, listing all properties
+ fputs(file_get, strcat(bd_save_piece(minigame, e), "\n"));
+ }
+ fclose(file_get);
+
+ return true;
+ }
+
+ return false;
+}
+
+void bd_load_level(entity minigame)
+{
+ // loads all items from the database file
+ string file_read, file_name;
+ float file_get;
+
+ file_name = strcat("minigames/bulldozer/storage_", minigame.bd_levelname, ".txt");
+ file_get = fopen(file_name, FILE_READ);
+ if(file_get < 0)
+ {
+ LOG_INFO("^3BULLDOZER: ^7could not find storage file ^3", file_name, "^7, no items were loaded\n");
+ }
+ else
+ {
+ for(;;)
+ {
+ file_read = fgets(file_get);
+ if(file_read == "")
+ break;
+ if(substring(file_read, 0, 2) == "//")
+ continue;
+ if(substring(file_read, 0, 1) == "#")
+ continue;
+ if(substring(file_read, 0, 9) == "nextlevel")
+ {
+ bd_set_nextlevel(minigame, file_read);
+ continue;
+ }
+
+ entity e;
+ e = bd_load_piece(minigame, file_read);
+ }
+ }
+ fclose(file_get);
+}
+
+void bd_close_editor(entity minigame)
+{
+ entity dozer = bd_find_dozer(minigame);
+ if(!dozer)
+ {
+ LOG_INFO("You need to place a bulldozer on the level to save it!\n");
+ return;
+ }
+
+ if(bd_save_level(minigame))
+ {
+ minigame.minigame_flags = BD_TURN_MOVE;
+ minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
+ }
+ else
+ {
+ LOG_INFO("You need to set the level name!\n");
+ return;
+ }
+}
+
+#ifdef SVQC
+
+// required function, handle server side events
+int bd_server_event(entity minigame, string event, ...)
+{
+ switch(event)
+ {
+ case "start":
+ {
+ if(minigame.bd_levelname) { strunzone(minigame.bd_levelname); }
+ minigame.bd_levelname = strzone(autocvar_sv_minigames_bulldozer_startlevel);
+ bd_setup_pieces(minigame);
+ minigame.minigame_flags = BD_TURN_MOVE;
+
+ return true;
+ }
+ case "end":
+ {
+ entity e = world;
+ while( (e = findentity(e, owner, minigame)) )
+ if(e.classname == "minigame_board_piece")
+ {
+ if(e.netname) { strunzone(e.netname); }
+ remove(e);
+ }
+
+ if(minigame.bd_nextlevel) { strunzone(minigame.bd_nextlevel); }
+ if(minigame.bd_levelname) { strunzone(minigame.bd_levelname); }
+ return false;
+ }
+ case "join":
+ {
+ int pl_num = minigame_count_players(minigame);
+
+ if(pl_num >= BD_TEAMS) { return false; }
+
+ return 1;
+ }
+ case "cmd":
+ {
+ switch(argv(0))
+ {
+ case "move":
+ bd_do_move(minigame, ...(0,entity), ((...(1,int)) >= 2 ? argv(1) : string_null), ((...(1,int)) >= 3 ? argv(2) : string_null), ((...(1,int)) >= 4 ? argv(3) : string_null));
+ return true;
+ case "next":
+ bd_next_match(minigame,...(0,entity), ((...(1,int) >= 2 ? argv(1) : string_null)));
+ return true;
+ case "restart":
+ bd_restart_match(minigame,...(0,entity));
+ return true;
+ case "edit":
+ bd_activate_editor(minigame,...(0,entity));
+ return true;
+ case "save":
+ bd_close_editor(minigame);
+ return true;
+ case "fill":
+ bd_do_fill(minigame, ...(0,entity), ((...(1,int)) >= 2 ? argv(1) : string_null), ((...(1,int)) >= 3 ? argv(2) : string_null));
+ return true;
+ }
+
+ return false;
+ }
+ case "network_send":
+ {
+ entity sent = ...(0,entity);
+ int sf = ...(1,int);
+ if ( sent.classname == "minigame_board_piece" && (sf & MINIG_SF_UPDATE) )
+ {
+ int letter = minigame_tile_letter(sent.netname);
+ int number = minigame_tile_number(sent.netname);
+
+ WriteByte(MSG_ENTITY,letter);
+ WriteByte(MSG_ENTITY,number);
+
+ WriteByte(MSG_ENTITY,sent.bd_tiletype);
+
+ int dx = sent.bd_dir_x;
+ int dy = sent.bd_dir_y;
+ if(dx == -1) dx = 2;
+ if(dy == -1) dy = 2;
+ WriteByte(MSG_ENTITY,dx);
+ WriteByte(MSG_ENTITY,dy);
+ }
+ else if(sent.classname == "minigame_player" && (sf & BD_SF_PLAYERMOVES))
+ WriteShort(MSG_ENTITY,sent.bd_moves);
+ return false;
+ }
+ }
+
+ return false;
+}
+
+
+#elif defined(CSQC)
+
+int bd_curr_tile;
+string bd_curr_pos;
+
+.entity bd_enemy;
+.bool bd_hide;
+
+vector bd_boardpos; // HUD board position
+vector bd_boardsize;// HUD board size
+
+string bd_get_tile_pic(int tileid)
+{
+ switch(tileid)
+ {
+ case BD_TILE_BOULDER: return "bd/boulder";
+ case BD_TILE_BRICK1: return "bd/brick1";
+ case BD_TILE_BRICK2: return "bd/brick2";
+ case BD_TILE_BRICK3: return "bd/brick3";
+ case BD_TILE_BRICK4: return "bd/brick4";
+ case BD_TILE_BRICK5: return "bd/brick5";
+ case BD_TILE_BRICK6: return "bd/brick6";
+ case BD_TILE_BRICK7: return "bd/brick7";
+ case BD_TILE_BRICK8: return "bd/brick8";
+ case BD_TILE_TARGET: return "bd/target";
+ case BD_TILE_DOZER: return "bd/dozer";
+ }
+
+ return string_null;
+}
+
+// Required function, draw the game board
+void bd_hud_board(vector pos, vector mySize)
+{
+ minigame_hud_fitsqare(pos, mySize);
+ bd_boardpos = pos;
+ bd_boardsize = mySize;
+
+ minigame_hud_simpleboard(pos,mySize,minigame_texture("bd/board"));
+
+ vector tile_size = minigame_hud_denormalize_size('1 1 0' / BD_TILE_SIZE,pos,mySize);
+ vector tile_pos;
+
+ entity e;
+ FOREACH_MINIGAME_ENTITY(e)
+ {
+ if(e.classname == "minigame_board_piece")
+ {
+ if(e.bd_tiletype == BD_TILE_TARGET)
+ {
+ e.bd_enemy = world;
+ e.bd_enemy = bd_find_piece(active_minigame, e.netname, false);
+ }
+ else if(e.bd_tiletype == BD_TILE_BOULDER)
+ {
+ e.bd_hide = false; // reset either way
+ e.bd_hide = ((bd_find_piece(active_minigame, e.netname, true)) != world);
+ }
+ }
+ }
+ FOREACH_MINIGAME_ENTITY(e)
+ {
+ if ( e.classname == "minigame_board_piece" )
+ {
+ if(e.bd_tiletype != BD_TILE_DOZER && !e.bd_hide) // hide boulders
+ {
+ tile_pos = minigame_tile_pos(e.netname,BD_NUM_CNT,BD_LET_CNT);
+ tile_pos = minigame_hud_denormalize(tile_pos,pos,mySize);
+
+ string thepiece = bd_get_tile_pic(e.bd_tiletype);
+
+ if(e.bd_enemy)
+ thepiece = "bd/boulder_target";
+
+ minigame_drawpic_centered( tile_pos,
+ minigame_texture(thepiece),
+ tile_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
+ }
+ }
+ }
+
+ // draw dozers on top, always
+ FOREACH_MINIGAME_ENTITY(e)
+ {
+ if ( e.classname == "minigame_board_piece" && e.bd_tiletype == BD_TILE_DOZER )
+ {
+ tile_pos = minigame_tile_pos(e.netname,BD_NUM_CNT,BD_LET_CNT);
+ tile_pos = minigame_hud_denormalize(tile_pos,pos,mySize);
+
+ vector thedir = e.bd_dir;
+ float theang = 0;
+
+ if(thedir_y == -1) { theang = M_PI; }
+ if(thedir_x == 1) { theang = M_PI/2; }
+ if(thedir_x == -1) { theang = M_PI*3/2; }
+
+ drawrotpic(tile_pos, theang, minigame_texture("bd/dozer"),
+ tile_size, tile_size/2, '1 1 1',
+ panel_fg_alpha, DRAWFLAG_NORMAL );
+ }
+ }
+
+ if(active_minigame.minigame_flags & BD_TURN_EDIT)
+ if(bd_valid_tile(bd_curr_pos))
+ {
+ entity piece = bd_find_piece(active_minigame, bd_curr_pos, false);
+ entity targ = bd_find_piece(active_minigame, bd_curr_pos, true);
+ string thepiece = ((piece || (targ && bd_curr_tile != BD_TILE_BOULDER)) ? "bd/delete" : bd_get_tile_pic(bd_curr_tile));
+
+ tile_pos = minigame_tile_pos(bd_curr_pos,BD_LET_CNT,BD_NUM_CNT);
+ tile_pos = minigame_hud_denormalize(tile_pos,pos,mySize);
+ if(bd_curr_tile == BD_TILE_DOZER)
+ {
+ drawrotpic(tile_pos, M_PI, minigame_texture("bd/dozer"),
+ tile_size, tile_size/2, '1 1 1',
+ panel_fg_alpha/2, DRAWFLAG_NORMAL );
+ }
+ else
+ {
+ minigame_drawpic_centered( tile_pos,
+ minigame_texture(thepiece),
+ tile_size, '1 1 1', panel_fg_alpha/2, DRAWFLAG_NORMAL );
+ }
+ }
+
+ if ( (active_minigame.minigame_flags & BD_TURN_LOSS) || (active_minigame.minigame_flags & BD_TURN_WIN) )
+ {
+ vector winfs = hud_fontsize*2;
+ string victory_text = "Game over!";
+
+ if(active_minigame.minigame_flags & BD_TURN_WIN)
+ victory_text = "Well done! Click 'Next Level' to continue";
+
+ vector win_pos = pos+eY*(mySize_y-winfs_y)/2;
+ vector win_sz;
+ win_sz = minigame_drawcolorcodedstring_wrapped(mySize_x,win_pos,
+ sprintf("%s", victory_text),
+ winfs, 0, DRAWFLAG_NORMAL, 0.5);
+
+ drawfill(win_pos-eY*hud_fontsize_y,win_sz+2*eY*hud_fontsize_y,'0.3 0.3 1',0.8,DRAWFLAG_ADDITIVE);
+
+ minigame_drawcolorcodedstring_wrapped(mySize_x,win_pos,
+ sprintf("%s", victory_text),
+ winfs, panel_fg_alpha, DRAWFLAG_NORMAL, 0.5);
+ }
+}
+
+
+// Required function, draw the game status panel
+void bd_hud_status(vector pos, vector mySize)
+{
+ HUD_Panel_DrawBg(1);
+ vector ts;
+ ts = minigame_drawstring_wrapped(mySize_x,pos,active_minigame.descriptor.message,
+ hud_fontsize * 2, '0.25 0.47 0.72', panel_fg_alpha, DRAWFLAG_NORMAL,0.5);
+
+ pos_y += ts_y;
+ mySize_y -= ts_y;
+
+ vector player_fontsize = hud_fontsize * 1.75;
+ ts_y = ( mySize_y - 2*player_fontsize_y ) / BD_TEAMS;
+ ts_x = mySize_x;
+ vector mypos;
+ vector tile_size = '48 48 0';
+
+ mypos = pos;
+ drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
+ mypos_y += player_fontsize_y;
+ drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+
+ entity e;
+ FOREACH_MINIGAME_ENTITY(e)
+ {
+ if ( e.classname == "minigame_player" )
+ {
+ mypos = pos;
+ minigame_drawcolorcodedstring_trunc(mySize_x,mypos,
+ GetPlayerName(e.minigame_playerslot-1),
+ player_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ mypos_y += player_fontsize_y;
+ string thepiece = "bd/dozer";
+ if(active_minigame.minigame_flags & BD_TURN_EDIT)
+ thepiece = bd_get_tile_pic(bd_curr_tile);
+ drawpic( mypos,
+ minigame_texture(thepiece),
+ tile_size * 0.7, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
+
+ mypos_x += tile_size_x;
+
+ drawstring(mypos,ftos(e.bd_moves),tile_size,
+ '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+ }
+}
+
+// Turn a set of flags into a help message
+string bd_turn_to_string(int turnflags)
+{
+ if ( turnflags & BD_TURN_LOSS )
+ return _("Better luck next time!");
+
+ if ( turnflags & BD_TURN_WIN )
+ if(random() > 0.5)
+ return _("Tubular! Press \"Next Level\" to continue!");
+ else
+ return _("Wicked! Press \"Next Level\" to continue!");
+
+ if( turnflags & BD_TURN_EDIT )
+ return _("Press the space bar to change your currently selected tile");
+
+ if ( turnflags & BD_TURN_MOVE )
+ return _("Push the boulders onto the targets");
+
+ return "";
+}
+
+// Make the correct move
+void bd_make_move(entity minigame, string dir)
+{
+ if ( minigame.minigame_flags == BD_TURN_MOVE )
+ {
+ minigame_cmd("move ", dir);
+ }
+}
+
+void bd_editor_make_move(entity minigame, string dir)
+{
+ if ( minigame.minigame_flags == BD_TURN_EDIT )
+ {
+ minigame_cmd("move ", bd_curr_pos, " ", ftos(bd_curr_tile), " ", dir);
+ }
+}
+
+void bd_editor_fill(entity minigame)
+{
+ if ( minigame.minigame_flags == BD_TURN_EDIT )
+ {
+ minigame_cmd("fill ", bd_curr_pos, " ", ftos(bd_curr_tile));
+ }
+}
+
+void bd_set_curr_pos(string s)
+{
+ if ( bd_curr_pos )
+ strunzone(bd_curr_pos);
+ if ( s )
+ s = strzone(s);
+ bd_curr_pos = s;
+}
+
+bool bd_normal_move(entity minigame, int themove)
+{
+ switch ( themove )
+ {
+ case K_RIGHTARROW:
+ case K_KP_RIGHTARROW:
+ bd_make_move(minigame, "r");
+ return true;
+ case K_LEFTARROW:
+ case K_KP_LEFTARROW:
+ bd_make_move(minigame, "l");
+ return true;
+ case K_UPARROW:
+ case K_KP_UPARROW:
+ bd_make_move(minigame, "u");
+ return true;
+ case K_DOWNARROW:
+ case K_KP_DOWNARROW:
+ bd_make_move(minigame, "d");
+ return true;
+ }
+
+ return false;
+}
+
+bool bd_change_dozer_angle(entity minigame)
+{
+ entity dozer = bd_find_piece(minigame, bd_curr_pos, false);
+ if(!dozer || dozer.bd_tiletype != BD_TILE_DOZER)
+ return false;
+
+ string thedir = "";
+ vector dir = dozer.bd_dir;
+ if(dir.x == 0 && dir.y == 0) { thedir = "r"; }
+
+ if(dir.x == 0 && dir.y == 1) { thedir = "r"; }
+ if(dir.x == 0 && dir.y ==-1) { thedir = "l"; }
+ if(dir.x ==-1 && dir.y == 0) { thedir = "u"; }
+ if(dir.x == 1 && dir.y == 0) { thedir = "d"; }
+
+ bd_editor_make_move(minigame, thedir);
+ return true;
+}
+
+bool bd_editor_move(entity minigame, int themove)
+{
+ switch ( themove )
+ {
+ case K_RIGHTARROW:
+ case K_KP_RIGHTARROW:
+ if ( ! bd_curr_pos )
+ bd_set_curr_pos("a3");
+ else
+ bd_set_curr_pos(minigame_relative_tile(bd_curr_pos,1,0,BD_NUM_CNT,BD_LET_CNT));
+ return true;
+ case K_LEFTARROW:
+ case K_KP_LEFTARROW:
+ if ( ! bd_curr_pos )
+ bd_set_curr_pos("c3");
+ else
+ bd_set_curr_pos(minigame_relative_tile(bd_curr_pos,-1,0,BD_NUM_CNT,BD_LET_CNT));
+ return true;
+ case K_UPARROW:
+ case K_KP_UPARROW:
+ if ( ! bd_curr_pos )
+ bd_set_curr_pos("a1");
+ else
+ bd_set_curr_pos(minigame_relative_tile(bd_curr_pos,0,1,BD_NUM_CNT,BD_LET_CNT));
+ return true;
+ case K_DOWNARROW:
+ case K_KP_DOWNARROW:
+ if ( ! bd_curr_pos )
+ bd_set_curr_pos("a3");
+ else
+ bd_set_curr_pos(minigame_relative_tile(bd_curr_pos,0,-1,BD_NUM_CNT,BD_LET_CNT));
+ return true;
+ case K_ENTER:
+ case K_KP_ENTER:
+ bd_editor_make_move(minigame, "");
+ return true;
+ case K_SPACE:
+ if(bd_change_dozer_angle(minigame))
+ return true;
+ bd_curr_tile += 1;
+ if(bd_curr_tile > BD_TILE_LAST)
+ bd_curr_tile = 1;
+ return true;
+ }
+
+ return false;
+}
+
+// Required function, handle client events
+int bd_client_event(entity minigame, string event, ...)
+{
+ switch(event)
+ {
+ case "activate":
+ {
+ minigame.message = bd_turn_to_string(minigame.minigame_flags);
+ bd_set_curr_pos("");
+ bd_curr_tile = BD_TILE_BRICK1;
+ return false;
+ }
+ case "key_pressed":
+ {
+ if(minigame.minigame_flags & BD_TURN_MOVE)
+ {
+ if(bd_normal_move(minigame, ...(0,int)))
+ return true;
+ }
+
+ if(minigame.minigame_flags & BD_TURN_EDIT)
+ {
+ if(bd_editor_move(minigame, ...(0,int)))
+ return true;
+ }
+
+ return false;
+ }
+ case "mouse_pressed":
+ {
+ if(minigame.minigame_flags & BD_TURN_EDIT)
+ {
+ if(...(0,int) == K_MOUSE1)
+ {
+ bd_editor_make_move(minigame, "");
+ return true;
+ }
+
+ if(...(0,int) == K_MOUSE2)
+ {
+ bd_editor_fill(minigame);
+ return true;
+ }
+ }
+
+ return false;
+ }
+ case "mouse_moved":
+ {
+ if(minigame.minigame_flags & BD_TURN_EDIT)
+ {
+ vector mouse_pos = minigame_hud_normalize(mousepos,bd_boardpos,bd_boardsize);
+ bd_set_curr_pos(minigame_tile_name(mouse_pos,BD_LET_CNT,BD_NUM_CNT));
+ if ( ! bd_valid_tile(bd_curr_pos) )
+ bd_set_curr_pos("");
+ }
+ return true;
+ }
+ case "network_receive":
+ {
+ entity sent = ...(0,entity);
+ int sf = ...(1,int);
+ if ( sent.classname == "minigame" )
+ {
+ if ( sf & MINIG_SF_UPDATE )
+ {
+ sent.message = bd_turn_to_string(sent.minigame_flags);
+ //if ( sent.minigame_flags & minigame_self.team )
+ minigame_prompt();
+ }
+ }
+ else if(sent.classname == "minigame_board_piece")
+ {
+ if(sf & MINIG_SF_UPDATE)
+ {
+ int letter = ReadByte();
+ int number = ReadByte();
+ if(sent.netname) { strunzone(sent.netname); }
+ sent.netname = strzone(minigame_tile_buildname(letter, number));
+
+ sent.bd_tiletype = ReadByte();
+
+ int dx = ReadByte();
+ int dy = ReadByte();
+
+ if(dx == 2) dx = -1;
+ if(dy == 2) dy = -1;
+
+ sent.bd_dir_x = dx;
+ sent.bd_dir_y = dy;
+ sent.bd_dir_z = 0;
+ }
+ }
+ else if(sent.classname == "minigame_player" && (sf & BD_SF_PLAYERMOVES))
+ sent.bd_moves = ReadShort(); // make this a byte when possible
+
+ return false;
+ }
+ case "menu_show":
+ {
+ HUD_MinigameMenu_CustomEntry(...(0,entity),_("Next Level"),"next");
+ HUD_MinigameMenu_CustomEntry(...(0,entity),_("Restart"),"restart");
+ HUD_MinigameMenu_CustomEntry(...(0,entity),_("Editor"),"edit");
+ HUD_MinigameMenu_CustomEntry(...(0,entity),_("Save"),"save");
+ return false;
+ }
+ case "menu_click":
+ {
+ if(...(0,string) == "next")
+ minigame_cmd("next");
+ if(...(0,string) == "restart")
+ minigame_cmd("restart");
+ if(...(0,string) == "edit")
+ minigame_cmd("edit");
+ if(...(0,string) == "save")
+ minigame_cmd("save");
+ return false;
+ }
+ }
+
+ return false;
+}
+
+#endif
\ No newline at end of file
#define FIELD(Flags, Type,Name) if ( sf & (Flags) ) Write##Type(MSG_ENTITY, self.Name);
-#define WriteVector(to,Name) WriteCoord(to,Name##_x); WriteCoord(to,Name##_y); WriteCoord(to,Name##_z)
-#define WriteVector2D(to,Name) WriteCoord(to,Name##_x); WriteCoord(to,Name##_y)
#define MSLE(Name,Fields) \
else if ( self.classname == #Name ) { \
if ( sf & MINIG_SF_CREATE ) WriteString(MSG_ENTITY,self.owner.netname); \
bool minigame_SendEntity(entity this, entity to, int sf);
-REGISTRY(Minigames, BITS(3))
+REGISTRY(Minigames, BITS(4))
#define Minigames_from(i) _Minigames_from(i, NULL)
-REGISTER_REGISTRY(RegisterMinigames)
+REGISTER_REGISTRY(Minigames)
REGISTRY_CHECK(Minigames)
#define REGISTER_MINIGAME(name,nicename) \
- REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, new(minigame_descriptor)); \
+ REGISTER(Minigames, MINIGAME_##name, m_id, new(minigame_descriptor)); \
int name##_server_event(entity, string, ...); \
- REGISTER_INIT_POST(MINIGAME, name) { \
+ REGISTER_INIT_POST(MINIGAME_##name) { \
make_pure(this); \
this.netname = strzone(strtolower(#name)); \
this.message = nicename; \
this.minigame_event = name##_server_event; \
} \
- REGISTER_INIT(MINIGAME, name)
+ REGISTER_INIT(MINIGAME_##name)
#endif
REGISTRY(Models, BITS(9))
#define Models_from(i) _Models_from(i, MDL_Null)
-REGISTER_REGISTRY(RegisterModels)
+REGISTER_REGISTRY(Models)
#define MODEL(name, path) \
string MDL_##name##_get() { return path; } \
- REGISTER(RegisterModels, MDL, Models, name, m_id, NEW(Model, MDL_##name##_get))
+ REGISTER(Models, MDL, name, m_id, NEW(Model, MDL_##name##_get))
PRECACHE(Models) {
FOREACH(Models, true, LAMBDA({
REGISTRY(Monsters, BITS(5))
#define Monsters_from(i) _Monsters_from(i, MON_Null)
#define get_monsterinfo(i) Monsters_from(i)
-REGISTER_REGISTRY(RegisterMonsters)
+REGISTER_REGISTRY(Monsters)
REGISTRY_CHECK(Monsters)
const int MON_FIRST = 1;
#define MON_LAST (Monsters_COUNT - 1)
/** If you register a new monster, make sure to add it to all.inc */
-#define REGISTER_MONSTER(id, inst) REGISTER(RegisterMonsters, MON, Monsters, id, monsterid, inst)
+#define REGISTER_MONSTER(id, inst) REGISTER(Monsters, MON, id, monsterid, inst)
REGISTER_MONSTER(Null, NEW(Monster));
Damage(head, self, self.realowner, (autocvar_g_monster_shambler_attack_lightning_damage_zap) * MONSTER_SKILLMOD(self), DEATH_MONSTER_SHAMBLER_ZAP.m_id, head.origin, '0 0 0');
}
- self.think = SUB_Remove;
+ self.think = SUB_Remove_self;
self.nextthink = time + 0.2;
}
}
else
{
- oldself.think = SUB_Remove;
+ oldself.think = SUB_Remove_self;
oldself.nextthink = time;
}
}
if(delaytoo)
if(time < self.msound_delay)
return; // too early
- GlobalSound(self.(samplefield), chan, VOICETYPE_PLAYERSOUND);
+ GlobalSound_string(self.(samplefield), chan, VOICETYPE_PLAYERSOUND);
self.msound_delay = time + sound_delay;
}
return true;
}
-void Monster_Reset()
-{SELFPARAM();
- setorigin(self, self.pos1);
- self.angles = self.pos2;
+void Monster_Reset(entity this)
+{
+ setorigin(this, this.pos1);
+ this.angles = this.pos2;
- Unfreeze(self); // remove any icy remains
+ Unfreeze(this); // remove any icy remains
- self.health = self.max_health;
- self.velocity = '0 0 0';
- self.enemy = world;
- self.goalentity = world;
- self.attack_finished_single[0] = 0;
- self.moveto = self.origin;
+ this.health = this.max_health;
+ this.velocity = '0 0 0';
+ this.enemy = world;
+ this.goalentity = world;
+ this.attack_finished_single[0] = 0;
+ this.moveto = this.origin;
}
void Monster_Dead_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
// number of monsters spawned with mobspawn command
totalspawned -= 1;
- self.think = SUB_Remove;
+ self.think = SUB_Remove_self;
self.nextthink = time + 0.1;
self.event_damage = func_null;
}
{
Violence_GibSplash(self, 1, 0.5, attacker);
- self.think = SUB_Remove;
+ self.think = SUB_Remove_self;
self.nextthink = time + 0.1;
}
}
-#include "mutator/buffs/module.inc"
+#include "mutator/waypoints/module.inc"
+
#include "mutator/itemstime.qc"
#include "mutator/multijump/module.inc"
#include "mutator/nades/module.inc"
#include "mutator/superspec/module.inc"
-#include "mutator/waypoints/module.inc"
// completely self contained
#include "mutator/bloodloss/module.inc"
#include "mutator/breakablehook/module.inc"
+#include "mutator/buffs/module.inc"
#include "mutator/campcheck/module.inc"
#include "mutator/cloaked/module.inc"
#include "mutator/damagetext/module.inc"
bool ret = MUTATORFUNCTION_##id##_hooks(mode); if (ret) return ret; \
} \
bool MUTATOR_##id##_check() { return dependence; } \
- REGISTER(RegisterMutators, MUTATOR, Mutators, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \
+ REGISTER(Mutators, MUTATOR, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \
{ this.mutatorcheck = MUTATOR_##id##_check; } \
[[accumulate]] bool MUTATORFUNCTION_##id(int mode)
/**/
MUTATOR_HOOKABLE(BuildGameplayTipsString, EV_BuildGameplayTipsString);
+#define EV_IsFlying(i, o) \
+ /**/ i(entity, MUTATOR_ARGV_0_entity) \
+ /**/
+MUTATOR_HOOKABLE(IsFlying, EV_IsFlying);
+
+#define EV_WP_Format(i, o) \
+ /**/ i(entity, MUTATOR_ARGV_0_entity) \
+ /**/ i(string, MUTATOR_ARGV_0_string) \
+ /**/ o(vector, MUTATOR_ARGV_0_vector) \
+ /**/ o(string, MUTATOR_ARGV_0_string) \
+ /**/
+MUTATOR_HOOKABLE(WP_Format, EV_WP_Format);
+
#endif
--- /dev/null
+REGISTER_BUFF(AMMO) {
+ this.m_prettyName = _("Ammo");
+ this.m_name = "ammo";
+ this.m_skin = 3;
+ this.m_color = '0.76 1 0.1';
+}
+BUFF_SPAWNFUNCS(ammo, BUFF_AMMO)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(ammoregen, BUFF_AMMO)
+
+REGISTER_BUFF(RESISTANCE) {
+ this.m_prettyName = _("Resistance");
+ this.m_name = "resistance";
+ this.m_skin = 0;
+ this.m_color = '0.36 1 0.07';
+}
+BUFF_SPAWNFUNCS(resistance, BUFF_RESISTANCE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(resistance, BUFF_RESISTANCE)
+
+REGISTER_BUFF(SPEED) {
+ this.m_prettyName = _("Speed");
+ this.m_name = "speed";
+ this.m_skin = 9;
+ this.m_color = '0.1 1 0.84';
+}
+BUFF_SPAWNFUNCS(speed, BUFF_SPEED)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(haste, BUFF_SPEED)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(scout, BUFF_SPEED)
+
+REGISTER_BUFF(MEDIC) {
+ this.m_prettyName = _("Medic");
+ this.m_name = "medic";
+ this.m_skin = 1;
+ this.m_color = '1 0.12 0';
+}
+BUFF_SPAWNFUNCS(medic, BUFF_MEDIC)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler, BUFF_MEDIC)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(medic, BUFF_MEDIC)
+
+REGISTER_BUFF(BASH) {
+ this.m_prettyName = _("Bash");
+ this.m_name = "bash";
+ this.m_skin = 5;
+ this.m_color = '1 0.39 0';
+}
+BUFF_SPAWNFUNCS(bash, BUFF_BASH)
+
+REGISTER_BUFF(VAMPIRE) {
+ this.m_prettyName = _("Vampire");
+ this.m_name = "vampire";
+ this.m_skin = 2;
+ this.m_color = '1 0 0.24';
+}
+BUFF_SPAWNFUNCS(vampire, BUFF_VAMPIRE)
+
+REGISTER_BUFF(DISABILITY) {
+ this.m_prettyName = _("Disability");
+ this.m_name = "disability";
+ this.m_skin = 7;
+ this.m_color = '0.94 0.3 1';
+}
+BUFF_SPAWNFUNCS(disability, BUFF_DISABILITY)
+
+REGISTER_BUFF(VENGEANCE) {
+ this.m_prettyName = _("Vengeance");
+ this.m_name = "vengeance";
+ this.m_skin = 15;
+ this.m_color = '1 0.23 0.61';
+}
+BUFF_SPAWNFUNCS(vengeance, BUFF_VENGEANCE)
+
+REGISTER_BUFF(JUMP) {
+ this.m_prettyName = _("Jump");
+ this.m_name = "jump";
+ this.m_skin = 10;
+ this.m_color = '0.24 0.78 1';
+}
+BUFF_SPAWNFUNCS(jump, BUFF_JUMP)
+
+REGISTER_BUFF(FLIGHT) {
+ this.m_prettyName = _("Flight");
+ this.m_name = "flight";
+ this.m_skin = 11;
+ this.m_color = '0.33 0.56 1';
+}
+BUFF_SPAWNFUNCS(flight, BUFF_FLIGHT)
+
+REGISTER_BUFF(INVISIBLE) {
+ this.m_prettyName = _("Invisible");
+ this.m_name = "invisible";
+ this.m_skin = 12;
+ this.m_color = '0.5 0.5 1';
+}
+BUFF_SPAWNFUNCS(invisible, BUFF_INVISIBLE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(invis, BUFF_INVISIBLE)
+
+REGISTER_BUFF(INFERNO) {
+ this.m_prettyName = _("Inferno");
+ this.m_name = "inferno";
+ this.m_skin = 16;
+ this.m_color = '1 0.62 0';
+}
+BUFF_SPAWNFUNCS(inferno, BUFF_INFERNO)
+
+REGISTER_BUFF(SWAPPER) {
+ this.m_prettyName = _("Swapper");
+ this.m_name = "swapper";
+ this.m_skin = 17;
+ this.m_color = '0.63 0.36 1';
+}
+BUFF_SPAWNFUNCS(swapper, BUFF_SWAPPER)
+
+REGISTER_BUFF(MAGNET) {
+ this.m_prettyName = _("Magnet");
+ this.m_name = "magnet";
+ this.m_skin = 18;
+ this.m_color = '1 0.95 0.18';
+}
+BUFF_SPAWNFUNCS(magnet, BUFF_MAGNET)
--- /dev/null
+#include "all.qh"
--- /dev/null
+#ifndef BUFFS_ALL_H
+#define BUFFS_ALL_H
+// Welcome to the stuff behind the scenes
+// Below, you will find the list of buffs
+// Add new buffs here!
+// Note: Buffs also need spawnfuncs, which are set below
+
+#include "../../../teams.qh"
+#include "../../../util.qh"
+
+REGISTER_WAYPOINT(Buff, _("Buff"), '1 0.5 0', 1);
+REGISTER_RADARICON(Buff, 1);
+
+REGISTRY(Buffs, BITS(4))
+#define Buffs_from(i) _Buffs_from(i, BUFF_Null)
+REGISTER_REGISTRY(Buffs)
+REGISTRY_CHECK(Buffs)
+
+#define REGISTER_BUFF(id) \
+ REGISTER(Buffs, BUFF_##id, m_id, NEW(Buff)); \
+ REGISTER_INIT_POST(BUFF_##id) { \
+ this.netname = this.m_name; \
+ this.m_itemid = BIT(this.m_id - 1); \
+ this.m_sprite = strzone(strcat("buff-", this.m_name)); \
+ } \
+ REGISTER_INIT(BUFF_##id)
+
+#include "../../../items/item/pickup.qh"
+CLASS(Buff, Pickup)
+ /** bit index */
+ ATTRIB(Buff, m_itemid, int, 0)
+ ATTRIB(Buff, m_name, string, "buff")
+ ATTRIB(Buff, m_color, vector, '1 1 1')
+ ATTRIB(Buff, m_prettyName, string, "Buff")
+ ATTRIB(Buff, m_skin, int, 0)
+ ATTRIB(Buff, m_sprite, string, "")
+ METHOD(Buff, display, void(entity this, void(string name, string icon) returns)) {
+ returns(this.m_prettyName, sprintf("/gfx/hud/%s/buff_%s", cvar_string("menu_skin"), this.m_name));
+ }
+#ifdef SVQC
+ METHOD(Buff, m_time, float(Buff this))
+ { return cvar(strcat("g_buffs_", this.netname, "_time")); }
+#endif
+ENDCLASS(Buff)
+
+#ifdef SVQC
+ // .int buffs = _STAT(BUFFS);
+ void buff_Init(entity ent);
+ void buff_Init_Compat(entity ent, entity replacement);
+ #define BUFF_SPAWNFUNC(e, b, t) spawnfunc(item_buff_##e) { \
+ self.buffs = b.m_itemid; \
+ self.team = t; \
+ buff_Init(self); \
+ }
+ #define BUFF_SPAWNFUNCS(e, b) \
+ BUFF_SPAWNFUNC(e, b, 0) \
+ BUFF_SPAWNFUNC(e##_team1, b, NUM_TEAM_1) \
+ BUFF_SPAWNFUNC(e##_team2, b, NUM_TEAM_2) \
+ BUFF_SPAWNFUNC(e##_team3, b, NUM_TEAM_3) \
+ BUFF_SPAWNFUNC(e##_team4, b, NUM_TEAM_4)
+ #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r) spawnfunc(item_##o) { buff_Init_Compat(self, r); }
+#else
+ #define BUFF_SPAWNFUNC(e, b, t)
+ #define BUFF_SPAWNFUNCS(e, b)
+ #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r)
+#endif
+
+REGISTER_BUFF(Null);
+BUFF_SPAWNFUNCS(random, BUFF_Null)
+
+#include "all.inc"
+
+#endif
#include "../../../triggers/target/music.qh"
#include "../../../gamemodes/all.qh"
-#include "../../../buffs/all.qh"
.float buff_time = _STAT(BUFF_TIME);
void buffs_DelayedInit();
if(self.buff_activetime) { buff_Waypoint_Spawn(self); }
}
-void buff_Reset()
-{SELFPARAM();
+void buff_Reset(entity this)
+{
if(autocvar_g_buffs_randomize)
- buff_NewType(self, self.buffs);
- self.owner = world;
+ buff_NewType(this, this.buffs);
+ this.owner = world;
buff_SetCooldown(autocvar_g_buffs_cooldown_activate);
buff_Waypoint_Reset();
- self.buff_activetime_updated = false;
+ this.buff_activetime_updated = false;
- if(autocvar_g_buffs_random_location || (self.spawnflags & 64))
- buff_Respawn(self);
+ if(autocvar_g_buffs_random_location || (this.spawnflags & 64))
+ buff_Respawn(this);
}
float buff_Customize()
MUTATOR_HOOKFUNCTION(buffs, OnEntityPreSpawn, CBC_ORDER_LAST)
{SELFPARAM();
+ if (self.classname == "item_flight" && cvar("g_buffs") && cvar("g_buffs_flight"))
+ {
+ buff_Init_Compat(self, BUFF_FLIGHT);
+ return true;
+ }
if(autocvar_g_buffs_replace_powerups)
switch(self.classname)
{
+#include "all.qc"
#ifdef SVQC
#include "buffs.qc"
#endif
+
+#ifdef IMPLEMENTATION
+
+string BUFF_NAME(int i)
+{
+ Buff b = Buffs_from(i);
+ return sprintf("%s%s", rgb_to_hexcolor(b.m_color), b.m_prettyName);
+}
+
+#ifndef MENUQC
+REGISTER_MUTATOR(buffs_flight, true);
+MUTATOR_HOOKFUNCTION(buffs_flight, IsFlying)
+{
+ noref entity e = MUTATOR_ARGV(0, entity);
+ return BUFFS_STAT(e) & BUFF_FLIGHT.m_itemid;
+}
+#endif
+
+#ifdef CSQC
+REGISTER_MUTATOR(cl_buffs, true);
+MUTATOR_HOOKFUNCTION(cl_buffs, HUD_Powerups_add)
+{
+ int allBuffs = STAT(BUFFS);
+ FOREACH(Buffs, it.m_itemid & allBuffs, LAMBDA(
+ addPowerupItem(it.m_prettyName, strcat("buff_", it.m_name), it.m_color, bound(0, STAT(BUFF_TIME) - time, 99), 60);
+ ));
+}
+MUTATOR_HOOKFUNCTION(cl_buffs, WP_Format)
+{
+ entity this = MUTATOR_ARGV(0, entity);
+ string s = MUTATOR_ARGV(0, string);
+ if (s == WP_Buff.netname || s == RADARICON_Buff.netname)
+ {
+ Buff b = Buffs_from(this.wp_extra);
+ MUTATOR_ARGV(0, vector) = b.m_color;
+ MUTATOR_ARGV(0, string) = b.m_prettyName;
+ return true;
+ }
+}
+
+#endif
+#endif
float autocvar_g_instagib_speed_highspeed;
#include "../../../../server/cl_client.qh"
-#include "../../../buffs/all.qh"
#include "../../../items/all.qc"
void instagib_extralife()
{SELFPARAM();
- self.max_health = 1;
StartItem(this, ITEM_ExtraLife);
}
frag_mirrordamage = 0;
}
- if((frag_target.buffs & BUFF_INVISIBLE.m_itemid) || (frag_target.items & ITEM_Invisibility.m_itemid))
+ if(frag_target.alpha && frag_target.alpha < 1)
yoda = 1;
return false;
return MUT_ITEMTOUCH_CONTINUE;
}
- if(self.max_health)
+ if(self.itemdef == ITEM_ExtraLife)
{
other.armorvalue = bound(other.armorvalue, 999, other.armorvalue + autocvar_g_instagib_extralives);
Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
float Item_ItemsTime_UpdateTime(entity e, float t)
{
bool isavailable = (t == 0);
- if (e.weapons & WEPSET_SUPERWEAPONS)
- {
- for (entity head = world; (head = nextent(head)); )
- {
- if (clienttype(head) != CLIENTTYPE_NOTACLIENT || !(head.weapons & WEPSET_SUPERWEAPONS) || head.instanceOfWeapon)
- continue;
- if (e == head)
- continue;
-
- if (head.scheduledrespawntime <= time)
- isavailable = true;
- else if (t == 0 || head.scheduledrespawntime < t)
- t = head.scheduledrespawntime;
- }
- }
- else
- {
- for (entity head = world; (head = nextent(head)); )
- {
- if (head.itemdef != e.itemdef)
- continue;
- if (e == head)
- continue;
-
- if (head.scheduledrespawntime <= time)
- isavailable = true;
- else if (t == 0 || head.scheduledrespawntime < t)
- t = head.scheduledrespawntime;
- }
- }
+ FOREACH_ENTITY(it.itemdef == e.itemdef || ((it.weapons & WEPSET_SUPERWEAPONS) && clienttype(it) == CLIENTTYPE_NOTACLIENT), LAMBDA(
+ if (e == it) continue;
+ if (it.scheduledrespawntime <= time)
+ isavailable = true;
+ else if (t == 0 || it.scheduledrespawntime < t)
+ t = it.scheduledrespawntime;
+ ));
if (isavailable)
t = -t; // let know the client there's another available item
return t;
Item_ItemsTime_ResetTimes();
// ALL the times need to be reset before .reset()ing each item
// since Item_Reset schedules respawn of superweapons and powerups
- for (entity e = NULL; (e = nextent(e)); )
- if (IS_NOT_A_CLIENT(e))
- {
- setself(e);
- if (self.reset)
- Item_ItemsTime_SetTime(self, 0);
- }
+ FOREACH_ENTITY(IS_NOT_A_CLIENT(it), LAMBDA(
+ if (it.reset) Item_ItemsTime_SetTime(it, 0);
+ ));
Item_ItemsTime_SetTimesForAllPlayers();
}
--- /dev/null
+EFFECT(0, NADE_EXPLODE_RED, "nade_red_explode")
+EFFECT(0, NADE_EXPLODE_BLUE, "nade_blue_explode")
+EFFECT(0, NADE_EXPLODE_YELLOW, "nade_yellow_explode")
+EFFECT(0, NADE_EXPLODE_PINK, "nade_pink_explode")
+EFFECT(0, NADE_EXPLODE_NEUTRAL, "nade_neutral_explode")
+entity EFFECT_NADE_EXPLODE(int teamid)
+{
+ switch (teamid) {
+ case NUM_TEAM_1: return EFFECT_NADE_EXPLODE_RED;
+ case NUM_TEAM_2: return EFFECT_NADE_EXPLODE_BLUE;
+ case NUM_TEAM_3: return EFFECT_NADE_EXPLODE_YELLOW;
+ case NUM_TEAM_4: return EFFECT_NADE_EXPLODE_PINK;
+ default: return EFFECT_NADE_EXPLODE_NEUTRAL;
+ }
+}
+
+EFFECT(1, NADE_TRAIL_RED, "nade_red")
+EFFECT(1, NADE_TRAIL_BLUE, "nade_blue")
+EFFECT(1, NADE_TRAIL_YELLOW, "nade_yellow")
+EFFECT(1, NADE_TRAIL_PINK, "nade_pink")
+EFFECT(1, NADE_TRAIL_NEUTRAL, "nade_neutral")
+entity EFFECT_NADE_TRAIL(int teamid)
+{
+ switch (teamid) {
+ case NUM_TEAM_1: return EFFECT_NADE_TRAIL_RED;
+ case NUM_TEAM_2: return EFFECT_NADE_TRAIL_BLUE;
+ case NUM_TEAM_3: return EFFECT_NADE_TRAIL_YELLOW;
+ case NUM_TEAM_4: return EFFECT_NADE_TRAIL_PINK;
+ default: return EFFECT_NADE_TRAIL_NEUTRAL;
+ }
+}
+
+EFFECT(1, NADE_TRAIL_BURN_RED, "nade_red_burn")
+EFFECT(1, NADE_TRAIL_BURN_BLUE, "nade_blue_burn")
+EFFECT(1, NADE_TRAIL_BURN_YELLOW, "nade_yellow_burn")
+EFFECT(1, NADE_TRAIL_BURN_PINK, "nade_pink_burn")
+EFFECT(1, NADE_TRAIL_BURN_NEUTRAL, "nade_neutral_burn")
+entity EFFECT_NADE_TRAIL_BURN(int teamid)
+{
+ switch (teamid) {
+ case NUM_TEAM_1: return EFFECT_NADE_TRAIL_BURN_RED;
+ case NUM_TEAM_2: return EFFECT_NADE_TRAIL_BURN_BLUE;
+ case NUM_TEAM_3: return EFFECT_NADE_TRAIL_BURN_YELLOW;
+ case NUM_TEAM_4: return EFFECT_NADE_TRAIL_BURN_PINK;
+ default: return EFFECT_NADE_TRAIL_BURN_NEUTRAL;
+ }
+}
-#ifdef SVQC
#include "nades.qc"
+#ifndef MENUQC
+#include "net.qc"
#endif
--- /dev/null
+#ifndef MENUQC
+#define NADE_PROJECTILE(i, projectile, trail) do { \
+ this.m_projectile[i] = projectile; \
+ this.m_trail[i] = trail; \
+} while (0)
+#else
+#define NADE_PROJECTILE(i, projectile, trail)
+#endif
+
+REGISTER_NADE(NORMAL) {
+ this.m_color = '1 1 1';
+ NADE_PROJECTILE(0, PROJECTILE_NADE, EFFECT_Null);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_BURN, EFFECT_Null);
+}
+
+REGISTER_NADE(NAPALM) {
+ this.m_color = '2 0.5 0';
+ this.m_name = _("Napalm grenade");
+ this.m_icon = "nade_napalm";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_NAPALM, EFFECT_TR_ROCKET);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_NAPALM_BURN, EFFECT_SPIDERBOT_ROCKET_TRAIL);
+}
+
+REGISTER_NADE(ICE) {
+ this.m_color = '0 0.5 2';
+ this.m_name = _("Ice grenade");
+ this.m_icon = "nade_ice";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_ICE, EFFECT_TR_NEXUIZPLASMA);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_ICE_BURN, EFFECT_RACER_ROCKET_TRAIL);
+}
+
+REGISTER_NADE(TRANSLOCATE) {
+ this.m_color = '1 0 1';
+ this.m_name = _("Translocate grenade");
+ this.m_icon = "nade_translocate";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_TRANSLOCATE, EFFECT_TR_CRYLINKPLASMA);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_TRANSLOCATE, EFFECT_TR_CRYLINKPLASMA);
+}
+
+REGISTER_NADE(SPAWN) {
+ this.m_color = '1 0.9 0';
+ this.m_name = _("Spawn grenade");
+ this.m_icon = "nade_spawn";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_SPAWN, EFFECT_NADE_TRAIL_YELLOW);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_SPAWN, EFFECT_NADE_TRAIL_YELLOW);
+}
+
+REGISTER_NADE(HEAL) {
+ this.m_color = '1 0 0';
+ this.m_name = _("Heal grenade");
+ this.m_icon = "nade_heal";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_HEAL, EFFECT_NADE_TRAIL_RED);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_HEAL_BURN, EFFECT_NADE_TRAIL_BURN_RED);
+}
+
+REGISTER_NADE(MONSTER) {
+ this.m_color = '0.25 0.75 0';
+ this.m_name = _("Monster grenade");
+ this.m_icon = "nade_monster";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_MONSTER, EFFECT_NADE_TRAIL_RED);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_MONSTER_BURN, EFFECT_NADE_TRAIL_BURN_RED);
+}
-#ifndef MUTATOR_NADES_H
-#define MUTATOR_NADES_H
+#include "nades.qh"
-#ifdef SVQC
-#include "../../../../server/mutators/mutator/gamemode_freezetag.qc"
+#ifdef IMPLEMENTATION
+
+#ifndef MENUQC
+entity Nade_TrailEffect(int proj, int nade_team)
+{
+ switch (proj)
+ {
+ case PROJECTILE_NADE: return EFFECT_NADE_TRAIL(nade_team);
+ case PROJECTILE_NADE_BURN: return EFFECT_NADE_TRAIL_BURN(nade_team);
+ }
+
+ FOREACH(Nades, true, LAMBDA(
+ for (int j = 0; j < 2; j++)
+ {
+ if (it.m_projectile[j] == proj)
+ {
+ string trail = it.m_trail[j].eent_eff_name;
+ if (trail) return it.m_trail[j];
+ break;
+ }
+ }
+ ));
+
+ return EFFECT_Null;
+}
#endif
-.entity nade;
-.entity fake_nade;
-.float nade_timer = _STAT(NADE_TIMER);
-.float nade_refire;
-.float bonus_nades = _STAT(NADE_BONUS);
-.float nade_special_time;
-.float bonus_nade_score = _STAT(NADE_BONUS_SCORE);
-.int nade_type = _STAT(NADE_BONUS_TYPE);
-.string pokenade_type;
-.entity nade_damage_target;
-.float cvar_cl_nade_type;
-.string cvar_cl_pokenade_type;
-.float toss_time;
-.float stat_healing_orb = _STAT(HEALING_ORB);
-.float stat_healing_orb_alpha = _STAT(HEALING_ORB_ALPHA);
-.float nade_show_particles;
-
-// Remove nades that are being thrown
-void nades_Clear(entity player);
-
-// Give a bonus grenade to a player
-void(entity player, float score) nades_GiveBonus;
-
-/**
- * called to adjust nade damage and force on hit
- */
-#define EV_Nade_Damage(i, o) \
- /** weapon */ i(entity, MUTATOR_ARGV_0_entity) \
- /** force */ i(vector, MUTATOR_ARGV_0_vector) \
- /**/ o(vector, MUTATOR_ARGV_0_vector) \
- /** damage */ i(float, MUTATOR_ARGV_0_float) \
- /**/ o(float, MUTATOR_ARGV_0_float) \
- /**/
-MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage);
+#ifdef CSQC
+REGISTER_MUTATOR(cl_nades, true);
+MUTATOR_HOOKFUNCTION(cl_nades, HUD_Draw_overlay)
+{
+ if (STAT(HEALING_ORB) <= time) return false;
+ MUTATOR_ARGV(0, vector) = NADE_TYPE_HEAL.m_color;
+ MUTATOR_ARGV(0, float) = STAT(HEALING_ORB_ALPHA);
+ return true;
+}
+MUTATOR_HOOKFUNCTION(cl_nades, Ent_Projectile)
+{
+ if (self.cnt == PROJECTILE_NAPALM_FOUNTAIN)
+ {
+ self.modelindex = 0;
+ self.traileffect = EFFECT_FIREBALL.m_id;
+ return true;
+ }
+ if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
+ {
+ setmodel(self, MDL_PROJECTILE_NADE);
+ entity trail = Nade_TrailEffect(self.cnt, self.team);
+ if (trail.eent_eff_name) self.traileffect = trail.m_id;
+ return true;
+ }
+}
+MUTATOR_HOOKFUNCTION(cl_nades, EditProjectile)
+{
+ if (self.cnt == PROJECTILE_NAPALM_FOUNTAIN)
+ {
+ loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY2), VOL_BASE, ATTEN_NORM);
+ self.mins = '-16 -16 -16';
+ self.maxs = '16 16 16';
+ }
+
+ entity nade_type = Nade_FromProjectile(self.cnt);
+ if (nade_type == NADE_TYPE_Null) return;
+ self.mins = '-16 -16 -16';
+ self.maxs = '16 16 16';
+ self.colormod = nade_type.m_color;
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ self.scale = 1.5;
+ self.avelocity = randomvec() * 720;
+
+ if (nade_type == NADE_TYPE_TRANSLOCATE || nade_type == NADE_TYPE_SPAWN)
+ self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+ else
+ self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
+}
+bool Projectile_isnade(int p)
+{
+ return Nade_FromProjectile(p) != NADE_TYPE_Null;
+}
+void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time)
+{
+ float bonusNades = STAT(NADE_BONUS);
+ float bonusProgress = STAT(NADE_BONUS_SCORE);
+ float bonusType = STAT(NADE_BONUS_TYPE);
+ Nade def = Nades_from(bonusType);
+ vector nadeColor = def.m_color;
+ string nadeIcon = def.m_icon;
+
+ vector iconPos, textPos;
+
+ if(autocvar_hud_panel_ammo_iconalign)
+ {
+ iconPos = myPos + eX * 2 * mySize.y;
+ textPos = myPos;
+ }
+ else
+ {
+ iconPos = myPos;
+ textPos = myPos + eX * mySize.y;
+ }
+
+ if(bonusNades > 0 || bonusProgress > 0)
+ {
+ DrawNadeProgressBar(myPos, mySize, bonusProgress, nadeColor);
+
+ if(autocvar_hud_panel_ammo_text)
+ drawstring_aspect(textPos, ftos(bonusNades), eX * (2/3) * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ if(draw_expanding)
+ drawpic_aspect_skin_expanding(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, expand_time);
+ drawpic_aspect_skin(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+}
#endif
-#ifdef IMPLEMENTATION
+#ifdef SVQC
-#include "../../../nades/all.qh"
#include "../../../gamemodes/all.qh"
#include "../../../monsters/spawn.qh"
#include "../../../monsters/sv_monsters.qh"
fn.colormod = Nades_from(n.nade_type).m_color;
fn.colormap = self.colormap;
fn.glowmod = self.glowmod;
- fn.think = SUB_Remove;
+ fn.think = SUB_Remove_self;
fn.nextthink = n.wait;
self.nade = n;
return false;
}
#endif
+#endif
--- /dev/null
+#ifndef NADES_ALL_H
+#define NADES_ALL_H
+
+#include "../../../teams.qh"
+
+// use slots 70-100
+const int PROJECTILE_NADE = 71;
+const int PROJECTILE_NADE_BURN = 72;
+const int PROJECTILE_NADE_NAPALM = 73;
+const int PROJECTILE_NADE_NAPALM_BURN = 74;
+const int PROJECTILE_NAPALM_FOUNTAIN = 75;
+const int PROJECTILE_NADE_ICE = 76;
+const int PROJECTILE_NADE_ICE_BURN = 77;
+const int PROJECTILE_NADE_TRANSLOCATE = 78;
+const int PROJECTILE_NADE_SPAWN = 79;
+const int PROJECTILE_NADE_HEAL = 80;
+const int PROJECTILE_NADE_HEAL_BURN = 81;
+const int PROJECTILE_NADE_MONSTER = 82;
+const int PROJECTILE_NADE_MONSTER_BURN = 83;
+
+REGISTRY(Nades, BITS(4))
+#define Nades_from(i) _Nades_from(i, NADE_TYPE_Null)
+REGISTER_REGISTRY(Nades)
+REGISTRY_CHECK(Nades)
+
+#define REGISTER_NADE(id) REGISTER(Nades, NADE_TYPE, id, m_id, NEW(Nade))
+
+CLASS(Nade, Object)
+ ATTRIB(Nade, m_id, int, 0)
+ ATTRIB(Nade, m_color, vector, '0 0 0')
+ ATTRIB(Nade, m_name, string, _("Grenade"))
+ ATTRIB(Nade, m_icon, string, "nade_normal")
+ ATTRIBARRAY(Nade, m_projectile, int, 2)
+ ATTRIBARRAY(Nade, m_trail, entity, 2)
+ METHOD(Nade, display, void(entity this, void(string name, string icon) returns)) {
+ returns(this.m_name, sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.m_icon));
+ }
+ENDCLASS(Nade)
+
+REGISTER_NADE(Null);
+
+Nade Nade_FromProjectile(int proj)
+{
+ FOREACH(Nades, true, LAMBDA(
+ for (int j = 0; j < 2; j++)
+ {
+ if (it.m_projectile[j] == proj) return it;
+ }
+ ));
+ return NADE_TYPE_Null;
+}
+
+#ifndef MENUQC
+#include "effects.inc"
+#endif
+
+#include "nades.inc"
+
+.float healer_lifetime;
+.float healer_radius;
+
+#ifdef SVQC
+
+.entity nade;
+.entity fake_nade;
+.float nade_timer = _STAT(NADE_TIMER);
+.float nade_refire;
+.float bonus_nades = _STAT(NADE_BONUS);
+.float nade_special_time;
+.float bonus_nade_score = _STAT(NADE_BONUS_SCORE);
+.int nade_type = _STAT(NADE_BONUS_TYPE);
+.string pokenade_type;
+.entity nade_damage_target;
+.float cvar_cl_nade_type;
+.string cvar_cl_pokenade_type;
+.float toss_time;
+.float stat_healing_orb = _STAT(HEALING_ORB);
+.float stat_healing_orb_alpha = _STAT(HEALING_ORB_ALPHA);
+.float nade_show_particles;
+
+bool healer_send(entity this, entity to, int sf);
+
+// Remove nades that are being thrown
+void nades_Clear(entity player);
+
+// Give a bonus grenade to a player
+void(entity player, float score) nades_GiveBonus;
+
+/**
+ * called to adjust nade damage and force on hit
+ */
+#define EV_Nade_Damage(i, o) \
+ /** weapon */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** force */ i(vector, MUTATOR_ARGV_0_vector) \
+ /**/ o(vector, MUTATOR_ARGV_0_vector) \
+ /** damage */ i(float, MUTATOR_ARGV_0_float) \
+ /**/ o(float, MUTATOR_ARGV_0_float) \
+ /**/
+MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage);
+
+#endif
+
+#endif
--- /dev/null
+#include "nades.qh"
+
+#ifdef IMPLEMENTATION
+
+#ifdef CSQC
+.float ltime;
+void healer_draw(entity this)
+{
+ float dt = time - self.move_time;
+ self.move_time = time;
+ if(dt <= 0)
+ return;
+
+ self.alpha = (self.ltime - time) / self.healer_lifetime;
+ self.scale = min((1 - self.alpha)*self.healer_lifetime*4,1)*self.healer_radius;
+}
+
+void healer_setup(entity e)
+{
+ setmodel(e, MDL_NADE_HEAL);
+
+ setorigin(e, e.origin);
+
+ float model_radius = e.maxs.x;
+ vector size = '1 1 1' * e.healer_radius / 2;
+ setsize(e,-size,size);
+ e.healer_radius = e.healer_radius/model_radius*0.6;
+
+ e.draw = healer_draw;
+ e.health = 255;
+ e.movetype = MOVETYPE_NONE;
+ e.solid = SOLID_NOT;
+ e.drawmask = MASK_NORMAL;
+ e.scale = 0.01;
+ e.avelocity = e.move_avelocity = '7 0 11';
+ e.colormod = '1 0 0';
+ e.renderflags |= RF_ADDITIVE;
+}
+#endif
+
+REGISTER_NET_LINKED(Nade_Heal)
+
+#ifdef CSQC
+NET_HANDLE(Nade_Heal, bool isNew)
+{
+ Net_Accept(Nade_Heal);
+ int sf = ReadByte();
+ if (sf & 1) {
+ this.origin_x = ReadCoord();
+ this.origin_y = ReadCoord();
+ this.origin_z = ReadCoord();
+ setorigin(this, this.origin);
+ this.healer_lifetime = ReadByte();
+ this.healer_radius = ReadShort();
+ this.ltime = time + ReadByte()/10.0;
+ // this.ltime = time + this.healer_lifetime;
+ healer_setup(this);
+ }
+ return true;
+}
+#endif
+
+#ifdef SVQC
+bool healer_send(entity this, entity to, int sf)
+{
+ int channel = MSG_ENTITY;
+ WriteHeader(channel, Nade_Heal);
+ WriteByte(channel, sf);
+ if (sf & 1) {
+ WriteCoord(channel, this.origin.x);
+ WriteCoord(channel, this.origin.y);
+ WriteCoord(channel, this.origin.z);
+
+ WriteByte(channel, this.healer_lifetime);
+ //WriteByte(MSG_ENTITY, this.ltime - time + 1);
+ WriteShort(channel, this.healer_radius);
+ // round time delta to a 1/10th of a second
+ WriteByte(channel, (this.ltime - time)*10.0+0.5);
+ }
+ return true;
+}
+#endif
+
+#endif
n = tokenize_console(nt_GetReplacement(e.netname, autocvar_g_new_toys_autoreplace));
- for(j = 0; j < n; ++j)
- for(k = WEP_FIRST; k <= WEP_LAST; ++k)
- if(get_weaponinfo(k).netname == argv(j))
+ for (j = 0; j < n; ++j)
+ for (k = WEP_FIRST; k <= WEP_LAST; ++k)
+ {
+ Weapon w = get_weaponinfo(k);
+ if (w.netname == argv(j))
{
- if(start_weapons & WepSet_FromWeapon(i))
- newdefault |= WepSet_FromWeapon(k);
- if(warmup_start_weapons & WepSet_FromWeapon(i))
- warmup_newdefault |= WepSet_FromWeapon(k);
+ WepSet seti = e.m_wepset;
+ WepSet setk = w.m_wepset;
+ if (start_weapons & seti) newdefault |= setk;
+ if (warmup_start_weapons & seti) warmup_newdefault |= setk;
}
+ }
}
newdefault &= start_weapons_defaultmask;
return false;
if(g_weaponarena)
{
- if(!(g_weaponarena_weapons & WepSet_FromWeapon(wpn)))
+ if(!(g_weaponarena_weapons & e.m_wepset))
return false;
}
else
else
Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_NEWWEAPON, nix_weapon);
- Weapon w = get_weaponinfo(nix_weapon);
- w.wr_resetplayer(w);
+ e.wr_resetplayer(e);
// all weapons must be fully loaded when we spawn
if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
self.weapons = '0 0 0';
if(g_nix_with_blaster)
self.weapons |= WEPSET(BLASTER);
- self.weapons |= WepSet_FromWeapon(nix_weapon);
+ self.weapons |= e.m_wepset;
if(self.switchweapon != nix_weapon)
if(!client_hasweapon(self, self.switchweapon, true, false))
return false;
}
-void _spawnfunc_weapon_hmg() { SELFPARAM(); spawnfunc_weapon_hmg(this); }
-void _spawnfunc_weapon_rpc() { SELFPARAM(); spawnfunc_weapon_rpc(this); }
+void self_spawnfunc_weapon_hmg() { SELFPARAM(); spawnfunc_weapon_hmg(this); }
+void self_spawnfunc_weapon_rpc() { SELFPARAM(); spawnfunc_weapon_rpc(this); }
MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
{SELFPARAM();
wep.team = self.team;
wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
wep.pickup_anyway = true;
- wep.think = _spawnfunc_weapon_hmg;
+ wep.think = self_spawnfunc_weapon_hmg;
wep.nextthink = time + 0.1;
return true;
}
wep.team = self.team;
wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
wep.pickup_anyway = true;
- wep.think = _spawnfunc_weapon_rpc;
+ wep.think = self_spawnfunc_weapon_rpc;
wep.nextthink = time + 0.1;
return true;
}
entity _item = self;
entity e;
- FOR_EACH_SPEC(e)
+ FOR_EACH_CLIENT(e) if (IS_SPEC(e) || IS_OBSERVER(e))
{
setself(e);
if(self.superspec_flags & SSF_ITEMMSG)
REGISTER_WAYPOINT(OnsGen, _("Generator"), '1 0.5 0', 1);
REGISTER_WAYPOINT(OnsGenShielded, _("Generator"), '1 0.5 0', 1);
-REGISTER_WAYPOINT(Buff, _("Buff"), '1 0.5 0', 1);
-
REGISTER_WAYPOINT(Weapon, _("Weapon"), '0 0 0', 1);
REGISTER_WAYPOINT(Monster, _("Monster"), '1 0 0', 1);
REGISTRY(Waypoints, BITS(6))
#define Waypoints_from(i) _Waypoints_from(i, WP_Null)
-REGISTER_REGISTRY(RegisterWaypoints)
+REGISTER_REGISTRY(Waypoints)
REGISTRY_CHECK(Waypoints)
/** If you register a new waypoint, make sure to add it to all.inc */
-#define REGISTER_WAYPOINT_(id, init) REGISTER(RegisterWaypoints, WP, Waypoints, id, m_id, init)
+#define REGISTER_WAYPOINT_(id, init) REGISTER(Waypoints, WP, id, m_id, init)
CLASS(Waypoint, Object)
ATTRIB(Waypoint, m_id, int, 0)
REGISTRY(RadarIcons, BITS(7))
#define RadarIcons_from(i) _RadarIcons_from(i, RADARICON_NONE)
-REGISTER_REGISTRY(RegisterRadarIcons)
+REGISTER_REGISTRY(RadarIcons)
REGISTRY_CHECK(RadarIcons)
.int m_radaricon;
-#define REGISTER_RADARICON(id, num) REGISTER(RegisterRadarIcons, RADARICON, RadarIcons, id, m_id, new(RadarIcon)) { make_pure(this); this.m_radaricon = num; this.netname = #id; }
+#define REGISTER_RADARICON(id, num) REGISTER(RadarIcons, RADARICON, id, m_id, new(RadarIcon)) { make_pure(this); this.m_radaricon = num; this.netname = #id; }
REGISTER_WAYPOINT(Null, "", '0 0 0', 1);
REGISTER_RADARICON(DOMPOINT, 1);
REGISTER_RADARICON(TAGGED, 1);
-REGISTER_RADARICON(Buff, 1);
REGISTER_RADARICON(Item, 1);
REGISTER_RADARICON(Vehicle, 1);
REGISTER_RADARICON(Weapon, 1);
self.draw2d = Draw_WaypointSprite;
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
self.iflags |= IFLAG_ORIGIN;
if (sendflags & 0x80)
self.helpme += servertime;
}
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
self.entremove = Ent_RemoveWaypointSprite;
}
{
if (s == WP_Weapon.netname || s == RADARICON_Weapon.netname) return get_weaponinfo(this.wp_extra).wpcolor;
if (s == WP_Item.netname || s == RADARICON_Item.netname) return Items_from(this.wp_extra).m_color;
- if (s == WP_Buff.netname || s == RADARICON_Buff.netname) return Buffs_from(this.wp_extra).m_color;
+ if (MUTATOR_CALLHOOK(WP_Format, this, s))
+ {
+ return MUTATOR_ARGV(0, vector);
+ }
return def;
}
if (s == WP_RaceStartFinish.netname) return (race_checkpointtime || race_mycheckpointtime) ? _("Finish") : _("Start");
if (s == WP_Weapon.netname) return get_weaponinfo(self.wp_extra).m_name;
if (s == WP_Item.netname) return Items_from(self.wp_extra).m_waypoint;
- if (s == WP_Buff.netname) return Buffs_from(self.wp_extra).m_prettyName;
if (s == WP_Monster.netname) return get_monsterinfo(self.wp_extra).monster_name;
+ if (MUTATOR_CALLHOOK(WP_Format, this, s))
+ {
+ return MUTATOR_ARGV(0, string);
+ }
// need to loop, as our netname could be one of three
FOREACH(Waypoints, it.netname == s, LAMBDA(
if (fabs(sa) > fabs(ca))
{
algnx = (sa < 0);
- algny = 0.5 - 0.5 * ca / fabs(sa);
+ float f = fabs(sa);
+ algny = 0.5 - 0.5 * (f ? (ca / f) : 0);
}
else
{
- algnx = 0.5 - 0.5 * sa / fabs(ca);
+ float f = fabs(ca);
+ algnx = 0.5 - 0.5 * (f ? (sa / f) : 0);
algny = (ca < 0);
}
if (autocvar_cl_hidewaypoints)
return; // fixed waypoint
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(self);
float t = GetPlayerColor(player_localnum) + 1;
+++ /dev/null
-#define NADE_PROJECTILE(i, projectile, trail) do { \
- this.m_projectile[i] = projectile; \
- this.m_trail[i] = trail; \
-} while (0)
-
-REGISTER_NADE(NORMAL) {
- this.m_color = '1 1 1';
- NADE_PROJECTILE(0, PROJECTILE_NADE, EFFECT_Null);
- NADE_PROJECTILE(1, PROJECTILE_NADE_BURN, EFFECT_Null);
-}
-
-REGISTER_NADE(NAPALM) {
- this.m_color = '2 0.5 0';
- this.m_name = _("Napalm grenade");
- this.m_icon = "nade_napalm";
- NADE_PROJECTILE(0, PROJECTILE_NADE_NAPALM, EFFECT_TR_ROCKET);
- NADE_PROJECTILE(1, PROJECTILE_NADE_NAPALM_BURN, EFFECT_SPIDERBOT_ROCKET_TRAIL);
-}
-
-REGISTER_NADE(ICE) {
- this.m_color = '0 0.5 2';
- this.m_name = _("Ice grenade");
- this.m_icon = "nade_ice";
- NADE_PROJECTILE(0, PROJECTILE_NADE_ICE, EFFECT_TR_NEXUIZPLASMA);
- NADE_PROJECTILE(1, PROJECTILE_NADE_ICE_BURN, EFFECT_RACER_ROCKET_TRAIL);
-}
-
-REGISTER_NADE(TRANSLOCATE) {
- this.m_color = '1 0 1';
- this.m_name = _("Translocate grenade");
- this.m_icon = "nade_translocate";
- NADE_PROJECTILE(0, PROJECTILE_NADE_TRANSLOCATE, EFFECT_TR_CRYLINKPLASMA);
- NADE_PROJECTILE(1, PROJECTILE_NADE_TRANSLOCATE, EFFECT_TR_CRYLINKPLASMA);
-}
-
-REGISTER_NADE(SPAWN) {
- this.m_color = '1 0.9 0';
- this.m_name = _("Spawn grenade");
- this.m_icon = "nade_spawn";
- NADE_PROJECTILE(0, PROJECTILE_NADE_SPAWN, EFFECT_NADE_TRAIL_YELLOW);
- NADE_PROJECTILE(1, PROJECTILE_NADE_SPAWN, EFFECT_NADE_TRAIL_YELLOW);
-}
-
-REGISTER_NADE(HEAL) {
- this.m_color = '1 0 0';
- this.m_name = _("Heal grenade");
- this.m_icon = "nade_heal";
- NADE_PROJECTILE(0, PROJECTILE_NADE_HEAL, EFFECT_NADE_TRAIL_RED);
- NADE_PROJECTILE(1, PROJECTILE_NADE_HEAL_BURN, EFFECT_NADE_TRAIL_BURN_RED);
-}
-
-REGISTER_NADE(MONSTER) {
- this.m_color = '0.25 0.75 0';
- this.m_name = _("Monster grenade");
- this.m_icon = "nade_monster";
- NADE_PROJECTILE(0, PROJECTILE_NADE_MONSTER, EFFECT_NADE_TRAIL_RED);
- NADE_PROJECTILE(1, PROJECTILE_NADE_MONSTER_BURN, EFFECT_NADE_TRAIL_BURN_RED);
-}
+++ /dev/null
-#include "all.qh"
-
-#if defined(CSQC)
- #include "../../client/defs.qh"
- #include "../buffs/all.qh"
- #include "../movetypes/movetypes.qh"
- #include "../../client/main.qh"
- #include "../../lib/csqcmodel/cl_model.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
- #include "../constants.qh"
- #include "../../server/constants.qh"
- #include "../turrets/sv_turrets.qh"
-#endif
-
-
-#ifdef CSQC
-.float ltime;
-void healer_draw(entity this)
-{
- float dt = time - self.move_time;
- self.move_time = time;
- if(dt <= 0)
- return;
-
- self.alpha = (self.ltime - time) / self.healer_lifetime;
- self.scale = min((1 - self.alpha)*self.healer_lifetime*4,1)*self.healer_radius;
-}
-
-void healer_setup(entity e)
-{
- setmodel(e, MDL_NADE_HEAL);
-
- setorigin(e, e.origin);
-
- float model_radius = e.maxs.x;
- vector size = '1 1 1' * e.healer_radius / 2;
- setsize(e,-size,size);
- e.healer_radius = e.healer_radius/model_radius*0.6;
-
- e.draw = healer_draw;
- e.health = 255;
- e.movetype = MOVETYPE_NONE;
- e.solid = SOLID_NOT;
- e.drawmask = MASK_NORMAL;
- e.scale = 0.01;
- e.avelocity = e.move_avelocity = '7 0 11';
- e.colormod = '1 0 0';
- e.renderflags |= RF_ADDITIVE;
-}
-#endif // CSQC
-
-REGISTER_NET_LINKED(Nade_Heal)
-#ifdef CSQC
-NET_HANDLE(Nade_Heal, bool isNew)
-{
- Net_Accept(Nade_Heal);
- int sf = ReadByte();
- if (sf & 1) {
- this.origin_x = ReadCoord();
- this.origin_y = ReadCoord();
- this.origin_z = ReadCoord();
- setorigin(this, this.origin);
- this.healer_lifetime = ReadByte();
- this.healer_radius = ReadShort();
- this.ltime = time + ReadByte()/10.0;
- // this.ltime = time + this.healer_lifetime;
- healer_setup(this);
- }
- return true;
-}
-#endif
-
-#ifdef SVQC
-bool healer_send(entity this, entity to, int sf)
-{
- int channel = MSG_ENTITY;
- WriteHeader(channel, Nade_Heal);
- WriteByte(channel, sf);
- if (sf & 1) {
- WriteCoord(channel, this.origin.x);
- WriteCoord(channel, this.origin.y);
- WriteCoord(channel, this.origin.z);
-
- WriteByte(channel, this.healer_lifetime);
- //WriteByte(MSG_ENTITY, this.ltime - time + 1);
- WriteShort(channel, this.healer_radius);
- // round time delta to a 1/10th of a second
- WriteByte(channel, (this.ltime - time)*10.0+0.5);
- }
- return true;
-}
-#endif // SVQC
+++ /dev/null
-#ifndef NADES_ALL_H
-#define NADES_ALL_H
-
-#include "../teams.qh"
-
-.float healer_lifetime;
-.float healer_radius;
-
-// use slots 70-100
-const int PROJECTILE_NADE = 71;
-const int PROJECTILE_NADE_BURN = 72;
-const int PROJECTILE_NADE_NAPALM = 73;
-const int PROJECTILE_NADE_NAPALM_BURN = 74;
-const int PROJECTILE_NAPALM_FOUNTAIN = 75;
-const int PROJECTILE_NADE_ICE = 76;
-const int PROJECTILE_NADE_ICE_BURN = 77;
-const int PROJECTILE_NADE_TRANSLOCATE = 78;
-const int PROJECTILE_NADE_SPAWN = 79;
-const int PROJECTILE_NADE_HEAL = 80;
-const int PROJECTILE_NADE_HEAL_BURN = 81;
-const int PROJECTILE_NADE_MONSTER = 82;
-const int PROJECTILE_NADE_MONSTER_BURN = 83;
-
-REGISTRY(Nades, BITS(4))
-#define Nades_from(i) _Nades_from(i, NADE_TYPE_Null)
-REGISTER_REGISTRY(RegisterNades)
-REGISTRY_CHECK(Nades)
-
-#define REGISTER_NADE(id) REGISTER(RegisterNades, NADE_TYPE, Nades, id, m_id, NEW(Nade))
-
-CLASS(Nade, Object)
- ATTRIB(Nade, m_id, int, 0)
- ATTRIB(Nade, m_color, vector, '0 0 0')
- ATTRIB(Nade, m_name, string, _("Grenade"))
- ATTRIB(Nade, m_icon, string, "nade_normal")
- ATTRIBARRAY(Nade, m_projectile, int, 2)
- ATTRIBARRAY(Nade, m_trail, entity, 2)
- METHOD(Nade, display, void(entity this, void(string name, string icon) returns)) {
- returns(this.m_name, sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.m_icon));
- }
-ENDCLASS(Nade)
-
-REGISTER_NADE(Null);
-
-#ifdef SVQC
-bool healer_send(entity this, entity to, int sf);
-#endif
-
-entity Nade_FromProjectile(float proj)
-{
- FOREACH(Nades, true, LAMBDA(
- for (int j = 0; j < 2; j++)
- {
- if (it.m_projectile[j] == proj) return it;
- }
- ));
- return NADE_TYPE_Null;
-}
-
-entity Nade_TrailEffect(int proj, int nade_team)
-{
- switch (proj)
- {
- case PROJECTILE_NADE: return EFFECT_NADE_TRAIL(nade_team);
- case PROJECTILE_NADE_BURN: return EFFECT_NADE_TRAIL_BURN(nade_team);
- }
-
- FOREACH(Nades, true, LAMBDA(
- for (int j = 0; j < 2; j++)
- {
- if (it.m_projectile[j] == proj)
- {
- string trail = it.m_trail[j].eent_eff_name;
- if (trail) return it.m_trail[j];
- break;
- }
- }
- ));
-
- return EFFECT_Null;
-}
-
-#include "all.inc"
-
-#endif
#ifdef SVQC
void sv_notice_join_think()
-{SELFPARAM();
- //NextLevel();
- float argc = tokenizebyseparator(autocvar_sv_join_notices, "|");
- if(argc > 0)
- {
- float i;
- for(i = argc - 1; i >= 0; --i)
- sv_notice_to(self.owner, argv(i), autocvar_sv_join_notices_time, false);
- }
- remove(self);
+{
+ SELFPARAM();
+ int argc = tokenizebyseparator(autocvar_sv_join_notices, "|");
+ if (argc <= 0) return;
+ for (int i = 0; i < argc; ++i)
+ sv_notice_to(this, argv(i), autocvar_sv_join_notices_time, false);
}
-void sv_notice_join()
-{SELFPARAM();
+void sv_notice_join(entity _to)
+{
// to-do: make sv_join_notices support per-entry times
- if(autocvar_sv_join_notices == "")
- return;
-
- entity n = spawn();
- n.owner = self;
- n.think = sv_notice_join_think;
- n.nextthink = time + 1;
+ if (autocvar_sv_join_notices == "") return;
+ defer(_to, 1, sv_notice_join_think);
}
void sv_notice_to(entity _to, string _notice, float _howlong, float _modal)
cl_notice_read();
return true;
}
+entity cl_notices;
+STATIC_INIT(cl_notice)
+{
+ cl_notices = LL_NEW();
+}
void cl_notice_read()
{
- //float _done;
- //float _modal;
entity _notice = new(sv_notice);
+ make_pure(_notice);
_notice.netname = strzone(ReadString());
_notice.alpha = ReadLong() + time;
_notice.skin = ReadByte();
+ LL_PUSH(cl_notices, _notice);
}
-float cl_notice_run()
+void cl_notice_run()
{
- entity _notes;
- string _notice;
- float m = false;
-
- _notes = findchain(classname, "sv_notice");
- if(!_notes)
- return false;
- #define M1 30
- #define M2 10
-
- vector v1, v2 = '0 0 0', v3;
- v1 = '1 1 0' * M1;
- v2_x = vid_conwidth - (2 * M1);
- v2_y = vid_conheight - (2 * M1);
-
+ bool flag = false;
+ LL_EACH(cl_notices, it.alpha > time, LAMBDA(flag = true; break));
+ if (!flag) return;
+ const int M1 = 30;
+ const int M2 = 10;
+
+ vector v1 = '1 1 0' * M1;
+ vector v2 = '0 0 0';
+ v2.x = vid_conwidth - (2 * M1);
+ v2.y = vid_conheight - (2 * M1);
drawfill(v1, v2, '0 0 0', 0.5, DRAWFLAG_NORMAL);
+
v1 = '1 1 0' * (M1 + M2);
- v2_x = vid_conwidth - (2 * (M1 + M2));
- v2_y = vid_conheight - (2 * (M1 + M2));
+ v2.x = vid_conwidth - (2 * (M1 + M2));
+ v2.y = vid_conheight - (2 * (M1 + M2));
drawfill(v1, v2, '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
- v3 = v1 + '10 10 0';
- #define OUT(s,z) drawcolorcodedstring(v3, s, '1 1 0' * z, 1, DRAWFLAG_NORMAL); v3_y += z + 4
+ vector v3 = v1 + '10 10 0';
+ #define OUT(s, z) do { drawcolorcodedstring(v3, s, '1 1 0' * z, 1, DRAWFLAG_NORMAL); v3.y += z + 4; } while (0)
OUT(_("^1Server notices:"), 32);
-
- //drawcolorcodedstring(v1 + '5 5 0', "^1Server notices:", '32 32 0', 1, DRAWFLAG_NORMAL);
- while(_notes)
- {
-
- _notice = sprintf(_("^7%s (^3%d sec left)"), _notes.netname , rint(_notes.alpha - time));
- OUT(_notice, 16);
-
- if(_notes.skin)
- m = true;
-
- if(_notes.alpha <= time)
- {
- _notes.think = SUB_Remove;
- _notes.nextthink = time;
- }
-
- _notes = _notes.chain;
- }
-
+ LL_EACH(cl_notices, it.alpha > time, LAMBDA(
+ string s = sprintf(_("^7%s (^3%d sec left)"), it.netname , rint(it.alpha - time));
+ OUT(s, 16);
+ ));
#undef OUT
- #undef M1
- #undef M2
-
- return m;
}
#endif // CSQC
void sv_notice_to(entity _to, string _notice, float _howlong, float _modal);
void sv_notice_toall(string _notice, float _howlong, float _modal);
-void sv_notice_join();
+void sv_notice_join(entity _to);
#endif
#ifdef CSQC
// todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input
// this way, we don't need to have duplicates like i.e. s2loc and s3loc?
+string BUFF_NAME(int i);
+
#define NOTIF_ARGUMENT_LIST \
ARG_CASE(ARG_CS_SV_HA, "s1", s1) \
ARG_CASE(ARG_CS_SV_HA, "s2", s2) \
ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
ARG_CASE(ARG_CS_SV, "item_wepname", WEP_NAME(f1)) \
- ARG_CASE(ARG_CS_SV, "item_buffname", sprintf("%s%s", rgb_to_hexcolor(Buffs_from(f1).m_color), Buffs_from(f1).m_prettyName)) \
- ARG_CASE(ARG_CS_SV, "f3buffname", sprintf("%s%s", rgb_to_hexcolor(Buffs_from(f3).m_color), Buffs_from(f3).m_prettyName)) \
+ ARG_CASE(ARG_CS_SV, "item_buffname", BUFF_NAME(f1)) \
+ ARG_CASE(ARG_CS_SV, "f3buffname", BUFF_NAME(f3)) \
ARG_CASE(ARG_CS_SV, "item_wepammo", (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \
ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \
noref float pmove_waterjumptime;
-const float unstick_count = 27;
-vector unstick_offsets[unstick_count] =
+#define unstick_offsets(X) \
+/* 1 no nudge (just return the original if this test passes) */ \
+ X(' 0.000 0.000 0.000') \
+/* 6 simple nudges */ \
+ X(' 0.000 0.000 0.125') X('0.000 0.000 -0.125') \
+ X('-0.125 0.000 0.000') X('0.125 0.000 0.000') \
+ X(' 0.000 -0.125 0.000') X('0.000 0.125 0.000') \
+/* 4 diagonal flat nudges */ \
+ X('-0.125 -0.125 0.000') X('0.125 -0.125 0.000') \
+ X('-0.125 0.125 0.000') X('0.125 0.125 0.000') \
+/* 8 diagonal upward nudges */ \
+ X('-0.125 0.000 0.125') X('0.125 0.000 0.125') \
+ X(' 0.000 -0.125 0.125') X('0.000 0.125 0.125') \
+ X('-0.125 -0.125 0.125') X('0.125 -0.125 0.125') \
+ X('-0.125 0.125 0.125') X('0.125 0.125 0.125') \
+/* 8 diagonal downward nudges */ \
+ X('-0.125 0.000 -0.125') X('0.125 0.000 -0.125') \
+ X(' 0.000 -0.125 -0.125') X('0.000 0.125 -0.125') \
+ X('-0.125 -0.125 -0.125') X('0.125 -0.125 -0.125') \
+ X('-0.125 0.125 -0.125') X('0.125 0.125 -0.125') \
+/**/
+
+void PM_ClientMovement_Unstick(entity this)
{
-// 1 no nudge (just return the original if this test passes)
- '0.000 0.000 0.000',
-// 6 simple nudges
- ' 0.000 0.000 0.125', '0.000 0.000 -0.125',
- '-0.125 0.000 0.000', '0.125 0.000 0.000',
- ' 0.000 -0.125 0.000', '0.000 0.125 0.000',
-// 4 diagonal flat nudges
- '-0.125 -0.125 0.000', '0.125 -0.125 0.000',
- '-0.125 0.125 0.000', '0.125 0.125 0.000',
-// 8 diagonal upward nudges
- '-0.125 0.000 0.125', '0.125 0.000 0.125',
- ' 0.000 -0.125 0.125', '0.000 0.125 0.125',
- '-0.125 -0.125 0.125', '0.125 -0.125 0.125',
- '-0.125 0.125 0.125', '0.125 0.125 0.125',
-// 8 diagonal downward nudges
- '-0.125 0.000 -0.125', '0.125 0.000 -0.125',
- ' 0.000 -0.125 -0.125', '0.000 0.125 -0.125',
- '-0.125 -0.125 -0.125', '0.125 -0.125 -0.125',
- '-0.125 0.125 -0.125', '0.125 0.125 -0.125',
-};
-
-void PM_ClientMovement_Unstick()
-{SELFPARAM();
- float i;
- for (i = 0; i < unstick_count; i++)
- {
- vector neworigin = unstick_offsets[i] + self.origin;
- tracebox(neworigin, PL_CROUCH_MIN, PL_CROUCH_MAX, neworigin, MOVE_NORMAL, self);
- if (!trace_startsolid)
- {
- setorigin(self, neworigin);
- return;// true;
- }
+ #define X(unstick_offset) \
+ { \
+ vector neworigin = unstick_offset + this.origin; \
+ tracebox(neworigin, PL_CROUCH_MIN, PL_CROUCH_MAX, neworigin, MOVE_NORMAL, this); \
+ if (!trace_startsolid) \
+ { \
+ setorigin(this, neworigin); \
+ return; \
+ } \
}
+ unstick_offsets(X);
+ #undef X
}
-void PM_ClientMovement_UpdateStatus(bool ground)
-{SELFPARAM();
+void PM_ClientMovement_UpdateStatus(entity this, bool ground)
+{
// make sure player is not stuck
- PM_ClientMovement_Unstick();
+ PM_ClientMovement_Unstick(this);
// set crouched
- if (PHYS_INPUT_BUTTON_CROUCH(self))
+ if (PHYS_INPUT_BUTTON_CROUCH(this))
{
- // wants to crouch, this always works..
- if (!IS_DUCKED(self))
- SET_DUCKED(self);
+ // wants to crouch, this always works
+ if (!IS_DUCKED(this)) SET_DUCKED(this);
}
else
{
- // wants to stand, if currently crouching we need to check for a
- // low ceiling first
- if (IS_DUCKED(self))
+ // wants to stand, if currently crouching we need to check for a low ceiling first
+ if (IS_DUCKED(this))
{
- tracebox(self.origin, PL_MIN, PL_MAX, self.origin, MOVE_NORMAL, self);
- if (!trace_startsolid)
- UNSET_DUCKED(self);
+ tracebox(this.origin, PL_MIN, PL_MAX, this.origin, MOVE_NORMAL, this);
+ if (!trace_startsolid) UNSET_DUCKED(this);
}
}
// set onground
- vector origin1 = self.origin + '0 0 1';
- vector origin2 = self.origin - '0 0 1';
+ vector origin1 = this.origin + '0 0 1';
+ vector origin2 = this.origin - '0 0 1';
- if(ground)
+ if (ground)
{
- tracebox(origin1, self.mins, self.maxs, origin2, MOVE_NORMAL, self);
- if (trace_fraction < 1.0 && trace_plane_normal_z > 0.7)
+ tracebox(origin1, this.mins, this.maxs, origin2, MOVE_NORMAL, this);
+ if (trace_fraction < 1.0 && trace_plane_normal.z > 0.7)
{
- SET_ONGROUND(self);
+ SET_ONGROUND(this);
// this code actually "predicts" an impact; so let's clip velocity first
- float f = self.velocity * trace_plane_normal;
- self.velocity -= f * trace_plane_normal;
+ this.velocity -= this.velocity * trace_plane_normal * trace_plane_normal;
}
else
- UNSET_ONGROUND(self);
+ UNSET_ONGROUND(this);
}
// set watertype/waterlevel
- origin1 = self.origin;
- origin1_z += self.mins_z + 1;
- self.waterlevel = WATERLEVEL_NONE;
+ origin1 = this.origin;
+ origin1.z += this.mins_z + 1;
+ this.waterlevel = WATERLEVEL_NONE;
int thepoint = pointcontents(origin1);
- self.watertype = (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME);
+ this.watertype = (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME);
- if(self.watertype)
+ if (this.watertype)
{
- self.waterlevel = WATERLEVEL_WETFEET;
- origin1_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5;
+ this.waterlevel = WATERLEVEL_WETFEET;
+ origin1.z = this.origin.z + (this.mins.z + this.maxs.z) * 0.5;
thepoint = pointcontents(origin1);
- if(thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
+ if (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
{
- self.waterlevel = WATERLEVEL_SWIMMING;
- origin1_z = self.origin_z + 22;
+ this.waterlevel = WATERLEVEL_SWIMMING;
+ origin1.z = this.origin.z + 22;
thepoint = pointcontents(origin1);
- if(thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
- self.waterlevel = WATERLEVEL_SUBMERGED;
+ if (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
+ this.waterlevel = WATERLEVEL_SUBMERGED;
}
}
- if(IS_ONGROUND(self) || self.velocity_z <= 0 || pmove_waterjumptime <= 0)
+ if (IS_ONGROUND(this) || this.velocity.z <= 0 || pmove_waterjumptime <= 0)
pmove_waterjumptime = 0;
}
vector trace3_plane_normal = '0 0 0';
- PM_ClientMovement_UpdateStatus(false);
+ PM_ClientMovement_UpdateStatus(this, false);
primalvelocity = self.velocity;
for(bump = 0, t = PHYS_INPUT_TIMELENGTH; bump < 8 && (self.velocity * self.velocity) > 0; bump++)
{
void PM_check_hitground()
{SELFPARAM();
#ifdef SVQC
- if (IS_ONGROUND(self))
- if (IS_PLAYER(self)) // no fall sounds for observers thank you very much
- if (self.wasFlying)
- {
- self.wasFlying = 0;
- if (self.waterlevel < WATERLEVEL_SWIMMING)
- if (time >= self.ladder_time)
- if (!self.hook)
- {
- self.nextstep = time + 0.3 + random() * 0.1;
- trace_dphitq3surfaceflags = 0;
- tracebox(self.origin, self.mins, self.maxs, self.origin - '0 0 1', MOVE_NOMONSTERS, self);
- if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOSTEPS))
- {
- if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
- GlobalSound(globalsound_metalfall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
- else
- GlobalSound(globalsound_fall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
- }
- }
- }
+ if (!IS_PLAYER(this)) return; // no fall sounds for observers thank you very much
+ if (!IS_ONGROUND(this)) return;
+ if (!this.wasFlying) return;
+ this.wasFlying = false;
+ if (this.waterlevel >= WATERLEVEL_SWIMMING) return;
+ if (time < this.ladder_time) return;
+ if (this.hook) return;
+ this.nextstep = time + 0.3 + random() * 0.1;
+ trace_dphitq3surfaceflags = 0;
+ tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
+ if ((trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOSTEPS)) return;
+ entity fall = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS) ? GS_FALL_METAL : GS_FALL;
+ GlobalSound(fall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
#endif
}
#endif
}
-void PM_walk(float buttons_prev, float maxspd_mod)
-{SELFPARAM();
- if (!WAS_ONGROUND(self))
+void PM_walk(entity this, float maxspd_mod)
+{
+ if (!WAS_ONGROUND(this))
{
#ifdef SVQC
if (autocvar_speedmeter)
- LOG_TRACE(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n"));
+ LOG_TRACE(strcat("landing velocity: ", vtos(this.velocity), " (abs: ", ftos(vlen(this.velocity)), ")\n"));
#endif
- if (self.lastground < time - 0.3)
- self.velocity *= (1 - PHYS_FRICTION_ONLAND);
+ if (this.lastground < time - 0.3)
+ this.velocity *= (1 - PHYS_FRICTION_ONLAND);
#ifdef SVQC
- if (self.jumppadcount > 1)
- LOG_TRACE(strcat(ftos(self.jumppadcount), "x jumppad combo\n"));
- self.jumppadcount = 0;
+ if (this.jumppadcount > 1)
+ LOG_TRACE(strcat(ftos(this.jumppadcount), "x jumppad combo\n"));
+ this.jumppadcount = 0;
#endif
}
// walking
- makevectors(self.v_angle.y * '0 1 0');
- vector wishvel = v_forward * self.movement.x
- + v_right * self.movement.y;
+ makevectors(this.v_angle.y * '0 1 0');
+ const vector wishvel = v_forward * this.movement.x
+ + v_right * this.movement.y;
// acceleration
- vector wishdir = normalize(wishvel);
+ const vector wishdir = normalize(wishvel);
float wishspeed = vlen(wishvel);
-
- wishspeed = min(wishspeed, PHYS_MAXSPEED(self) * maxspd_mod);
- if (IS_DUCKED(self))
- wishspeed *= 0.5;
+ wishspeed = min(wishspeed, PHYS_MAXSPEED(this) * maxspd_mod);
+ if (IS_DUCKED(this)) wishspeed *= 0.5;
// apply edge friction
- float f = vlen(vec2(self.velocity));
- if (f > 0)
+ const float f2 = vlen2(vec2(this.velocity));
+ if (f2 > 0)
{
- float realfriction;
trace_dphitq3surfaceflags = 0;
- tracebox(self.origin, self.mins, self.maxs, self.origin - '0 0 1', MOVE_NOMONSTERS, self);
+ tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
// TODO: apply edge friction
// apply ground friction
- if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
- realfriction = PHYS_FRICTION_SLICK;
- else
- realfriction = PHYS_FRICTION;
+ const int realfriction = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
+ ? PHYS_FRICTION_SLICK
+ : PHYS_FRICTION;
+ float f = sqrt(f2);
f = 1 - PHYS_INPUT_TIMELENGTH * realfriction * ((f < PHYS_STOPSPEED) ? (PHYS_STOPSPEED / f) : 1);
f = max(0, f);
- self.velocity *= f;
+ this.velocity *= f;
/*
Mathematical analysis time!
v >= PHYS_STOPSPEED * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION)
*/
}
- float addspeed = wishspeed - self.velocity * wishdir;
+ const float addspeed = wishspeed - this.velocity * wishdir;
if (addspeed > 0)
{
- float accelspeed = min(PHYS_ACCELERATE * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed);
- self.velocity += accelspeed * wishdir;
+ const float accelspeed = min(PHYS_ACCELERATE * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed);
+ this.velocity += accelspeed * wishdir;
}
- float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(self) * PHYS_INPUT_TIMELENGTH;
+ const float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH;
if (!(GAMEPLAYFIX_NOGRAVITYONGROUND))
- self.velocity_z -= g * (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1);
- if (self.velocity * self.velocity)
+ this.velocity_z -= g * (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1);
+ if (vdist(this.velocity, >, 0))
PM_ClientMovement_Move();
if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
- if (!IS_ONGROUND(self) || !GAMEPLAYFIX_NOGRAVITYONGROUND)
- self.velocity_z -= g * 0.5;
+ if (!IS_ONGROUND(this) || !GAMEPLAYFIX_NOGRAVITYONGROUND)
+ this.velocity_z -= g * 0.5;
}
void PM_air(float buttons_prev, float maxspd_mod)
return true;
}
-void PM_Main()
-{SELFPARAM();
- int buttons = PHYS_INPUT_BUTTON_MASK(self);
+void PM_Main(entity this)
+{
+ int buttons = PHYS_INPUT_BUTTON_MASK(this);
#ifdef CSQC
- self.items = getstati(STAT_ITEMS, 0, 24);
+ this.items = getstati(STAT_ITEMS, 0, 24);
- self.movement = PHYS_INPUT_MOVEVALUES(self);
+ this.movement = PHYS_INPUT_MOVEVALUES(this);
- vector oldv_angle = self.v_angle;
- vector oldangles = self.angles; // we need to save these, as they're abused by other code
- self.v_angle = PHYS_INPUT_ANGLES(self);
- self.angles = PHYS_WORLD_ANGLES(self);
+ vector oldv_angle = this.v_angle;
+ vector oldangles = this.angles; // we need to save these, as they're abused by other code
+ this.v_angle = PHYS_INPUT_ANGLES(this);
+ this.angles = PHYS_WORLD_ANGLES(this);
- self.team = myteam + 1; // is this correct?
- if (!(PHYS_INPUT_BUTTON_JUMP(self))) // !jump
- UNSET_JUMP_HELD(self); // canjump = true
+ this.team = myteam + 1; // is this correct?
+ if (!(PHYS_INPUT_BUTTON_JUMP(this))) // !jump
+ UNSET_JUMP_HELD(this); // canjump = true
pmove_waterjumptime -= PHYS_INPUT_TIMELENGTH;
- PM_ClientMovement_UpdateStatus(true);
+ PM_ClientMovement_UpdateStatus(this, true);
#endif
#ifdef SVQC
Physics_UpdateStats(this, maxspeed_mod);
- if (self.PlayerPhysplug)
- if (self.PlayerPhysplug())
+ if (this.PlayerPhysplug)
+ if (this.PlayerPhysplug())
return;
#endif
#ifdef SVQC
if (sv_maxidle > 0)
{
- if (buttons != self.buttons_old || self.movement != self.movement_old || self.v_angle != self.v_angle_old)
- self.parm_idlesince = time;
+ if (buttons != this.buttons_old || this.movement != this.movement_old || this.v_angle != this.v_angle_old)
+ this.parm_idlesince = time;
}
#endif
- int buttons_prev = self.buttons_old;
- self.buttons_old = buttons;
- self.movement_old = self.movement;
- self.v_angle_old = self.v_angle;
+ int buttons_prev = this.buttons_old;
+ this.buttons_old = buttons;
+ this.movement_old = this.movement;
+ this.v_angle_old = this.v_angle;
PM_check_nickspam();
PM_check_punch();
#ifdef SVQC
- if (IS_BOT_CLIENT(self))
+ if (IS_BOT_CLIENT(this))
{
if (playerdemo_read())
return;
bot_think();
}
-
- if (IS_PLAYER(self))
-#endif
- {
- bool not_allowed_to_move = false;
-#ifdef SVQC
- if (time < game_starttime)
- not_allowed_to_move = true;
#endif
- if (not_allowed_to_move)
- {
- self.velocity = '0 0 0';
- self.movetype = MOVETYPE_NONE;
#ifdef SVQC
- self.disableclientprediction = 2;
-#endif
+ if (IS_PLAYER(this))
+ {
+ const bool allowed_to_move = (time >= game_starttime);
+ if (!allowed_to_move)
+ {
+ this.velocity = '0 0 0';
+ this.movetype = MOVETYPE_NONE;
+ this.disableclientprediction = 2;
}
-#ifdef SVQC
- else if (self.disableclientprediction == 2)
+ else if (this.disableclientprediction == 2)
{
- if (self.movetype == MOVETYPE_NONE)
- self.movetype = MOVETYPE_WALK;
- self.disableclientprediction = 0;
+ if (this.movetype == MOVETYPE_NONE)
+ this.movetype = MOVETYPE_WALK;
+ this.disableclientprediction = 0;
}
-#endif
}
+#endif
#ifdef SVQC
- if (self.movetype == MOVETYPE_NONE)
+ if (this.movetype == MOVETYPE_NONE)
return;
// when we get here, disableclientprediction cannot be 2
- self.disableclientprediction = 0;
+ this.disableclientprediction = 0;
#endif
viewloc_PlayerPhysics();
maxspeed_mod = 1;
- if (self.in_swamp)
- maxspeed_mod *= self.swamp_slowdown; //cvar("g_balance_swamp_moverate");
+ if (this.in_swamp)
+ maxspeed_mod *= this.swamp_slowdown; //cvar("g_balance_swamp_moverate");
// conveyors: first fix velocity
- if (self.conveyor.state)
- self.velocity -= self.conveyor.movedir;
+ if (this.conveyor.state)
+ this.velocity -= this.conveyor.movedir;
#ifdef SVQC
MUTATOR_CALLHOOK(PlayerPhysics);
// }
#ifdef SVQC
- if (!IS_PLAYER(self))
+ if (!IS_PLAYER(this))
{
maxspeed_mod = autocvar_sv_spectator_speed_multiplier;
- if (!self.spectatorspeed)
- self.spectatorspeed = maxspeed_mod;
- if (self.impulse && self.impulse <= 19 || (self.impulse >= 200 && self.impulse <= 209) || (self.impulse >= 220 && self.impulse <= 229))
+ if (!this.spectatorspeed)
+ this.spectatorspeed = maxspeed_mod;
+ if (this.impulse && this.impulse <= 19 || (this.impulse >= 200 && this.impulse <= 209) || (this.impulse >= 220 && this.impulse <= 229))
{
- if (self.lastclassname != "player")
+ if (this.lastclassname != "player")
{
- if (self.impulse == 10 || self.impulse == 15 || self.impulse == 18 || (self.impulse >= 200 && self.impulse <= 209))
- self.spectatorspeed = bound(1, self.spectatorspeed + 0.5, 5);
- else if (self.impulse == 11)
- self.spectatorspeed = maxspeed_mod;
- else if (self.impulse == 12 || self.impulse == 16 || self.impulse == 19 || (self.impulse >= 220 && self.impulse <= 229))
- self.spectatorspeed = bound(1, self.spectatorspeed - 0.5, 5);
- else if (self.impulse >= 1 && self.impulse <= 9)
- self.spectatorspeed = 1 + 0.5 * (self.impulse - 1);
+ if (this.impulse == 10 || this.impulse == 15 || this.impulse == 18 || (this.impulse >= 200 && this.impulse <= 209))
+ this.spectatorspeed = bound(1, this.spectatorspeed + 0.5, 5);
+ else if (this.impulse == 11)
+ this.spectatorspeed = maxspeed_mod;
+ else if (this.impulse == 12 || this.impulse == 16 || this.impulse == 19 || (this.impulse >= 220 && this.impulse <= 229))
+ this.spectatorspeed = bound(1, this.spectatorspeed - 0.5, 5);
+ else if (this.impulse >= 1 && this.impulse <= 9)
+ this.spectatorspeed = 1 + 0.5 * (this.impulse - 1);
} // otherwise just clear
- self.impulse = 0;
+ this.impulse = 0;
}
- maxspeed_mod = self.spectatorspeed;
+ maxspeed_mod = this.spectatorspeed;
}
- float spd = max(PHYS_MAXSPEED(self), PHYS_MAXAIRSPEED(self)) * maxspeed_mod;
- if(self.speed != spd)
+ float spd = max(PHYS_MAXSPEED(this), PHYS_MAXAIRSPEED(this)) * maxspeed_mod;
+ if(this.speed != spd)
{
- self.speed = spd;
+ this.speed = spd;
string temps = ftos(spd);
- stuffcmd(self, strcat("cl_forwardspeed ", temps, "\n"));
- stuffcmd(self, strcat("cl_backspeed ", temps, "\n"));
- stuffcmd(self, strcat("cl_sidespeed ", temps, "\n"));
- stuffcmd(self, strcat("cl_upspeed ", temps, "\n"));
+ stuffcmd(this, strcat("cl_forwardspeed ", temps, "\n"));
+ stuffcmd(this, strcat("cl_backspeed ", temps, "\n"));
+ stuffcmd(this, strcat("cl_sidespeed ", temps, "\n"));
+ stuffcmd(this, strcat("cl_upspeed ", temps, "\n"));
}
- if(self.stat_jumpspeedcap_min != PHYS_JUMPSPEEDCAP_MIN)
+ if(this.stat_jumpspeedcap_min != PHYS_JUMPSPEEDCAP_MIN)
{
- self.stat_jumpspeedcap_min = PHYS_JUMPSPEEDCAP_MIN;
- stuffcmd(self, strcat("cl_jumpspeedcap_min ", PHYS_JUMPSPEEDCAP_MIN, "\n"));
+ this.stat_jumpspeedcap_min = PHYS_JUMPSPEEDCAP_MIN;
+ stuffcmd(this, strcat("cl_jumpspeedcap_min ", PHYS_JUMPSPEEDCAP_MIN, "\n"));
}
- if(self.stat_jumpspeedcap_max != PHYS_JUMPSPEEDCAP_MAX)
+ if(this.stat_jumpspeedcap_max != PHYS_JUMPSPEEDCAP_MAX)
{
- self.stat_jumpspeedcap_min = PHYS_JUMPSPEEDCAP_MAX;
- stuffcmd(self, strcat("cl_jumpspeedcap_max ", PHYS_JUMPSPEEDCAP_MAX, "\n"));
+ this.stat_jumpspeedcap_min = PHYS_JUMPSPEEDCAP_MAX;
+ stuffcmd(this, strcat("cl_jumpspeedcap_max ", PHYS_JUMPSPEEDCAP_MAX, "\n"));
}
#endif
- if(PHYS_DEAD(self))
+ if(PHYS_DEAD(this))
{
// handle water here
- vector midpoint = ((self.absmin + self.absmax) * 0.5);
+ vector midpoint = ((this.absmin + this.absmax) * 0.5);
if(pointcontents(midpoint) == CONTENT_WATER)
{
- self.velocity = self.velocity * 0.5;
+ this.velocity = this.velocity * 0.5;
// do we want this?
//if(pointcontents(midpoint + '0 0 2') == CONTENT_WATER)
- //{ self.velocity_z = 70; }
+ //{ this.velocity_z = 70; }
}
goto end;
}
#ifdef SVQC
- if (!self.fixangle && !g_bugrigs)
- self.angles = '0 1 0' * self.v_angle.y;
+ if (!this.fixangle && !g_bugrigs)
+ this.angles = '0 1 0' * this.v_angle.y;
#endif
PM_check_hitground();
- if(IsFlying(self))
- self.wasFlying = 1;
+ if(IsFlying(this))
+ this.wasFlying = 1;
- if (IS_PLAYER(self))
+ if (IS_PLAYER(this))
CheckPlayerJump();
- if (self.flags & FL_WATERJUMP)
+ if (this.flags & FL_WATERJUMP)
{
- self.velocity_x = self.movedir_x;
- self.velocity_y = self.movedir_y;
- if (time > self.teleport_time || self.waterlevel == WATERLEVEL_NONE)
+ this.velocity_x = this.movedir.x;
+ this.velocity_y = this.movedir.y;
+ if (time > this.teleport_time || this.waterlevel == WATERLEVEL_NONE)
{
- self.flags &= ~FL_WATERJUMP;
- self.teleport_time = 0;
+ this.flags &= ~FL_WATERJUMP;
+ this.teleport_time = 0;
}
}
#ifdef SVQC
- else if (g_bugrigs && IS_PLAYER(self))
+ else if (g_bugrigs && IS_PLAYER(this))
RaceCarPhysics();
#endif
- else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY || (BUFFS_STAT(self) & BUFF_FLIGHT.m_itemid))
+ else if (this.movetype == MOVETYPE_NOCLIP || this.movetype == MOVETYPE_FLY || this.movetype == MOVETYPE_FLY_WORLDONLY || MUTATOR_CALLHOOK(IsFlying, this))
PM_fly(maxspeed_mod);
- else if (self.waterlevel >= WATERLEVEL_SWIMMING)
+ else if (this.waterlevel >= WATERLEVEL_SWIMMING)
PM_swim(maxspeed_mod);
- else if (time < self.ladder_time)
+ else if (time < this.ladder_time)
PM_ladder(maxspeed_mod);
- else if (ITEMS_STAT(self) & IT_USING_JETPACK)
+ else if (ITEMS_STAT(this) & IT_USING_JETPACK)
PM_jetpack(maxspeed_mod);
- else if (IS_ONGROUND(self))
- PM_walk(buttons_prev, maxspeed_mod);
+ else if (IS_ONGROUND(this))
+ PM_walk(this, maxspeed_mod);
else
PM_air(buttons_prev, maxspeed_mod);
PM_check_vortex();
:end
- if (IS_ONGROUND(self))
- self.lastground = time;
+ if (IS_ONGROUND(this))
+ this.lastground = time;
// conveyors: then break velocity again
- if(self.conveyor.state)
- self.velocity += self.conveyor.movedir;
+ if(this.conveyor.state)
+ this.velocity += this.conveyor.movedir;
- self.lastflags = self.flags;
+ this.lastflags = this.flags;
- self.lastclassname = self.classname;
+ this.lastclassname = this.classname;
#ifdef CSQC
- self.v_angle = oldv_angle;
- self.angles = oldangles;
+ this.v_angle = oldv_angle;
+ this.angles = oldangles;
#endif
}
-#ifdef SVQC
+#if defined(SVQC)
void SV_PlayerPhysics()
#elif defined(CSQC)
-void CSQC_ClientMovement_PlayerMove_Frame()
+void CSQC_ClientMovement_PlayerMove_Frame(entity this)
#endif
-{SELFPARAM();
- PM_Main();
-
+{
+#ifdef SVQC
+ SELFPARAM();
+#endif
+ PM_Main(this);
#ifdef CSQC
- self.pmove_flags =
- ((self.flags & FL_DUCKED) ? PMF_DUCKED : 0) |
- (!(self.flags & FL_JUMPRELEASED) ? 0 : PMF_JUMP_HELD) |
- ((self.flags & FL_ONGROUND) ? PMF_ONGROUND : 0);
+ this.pmove_flags =
+ ((this.flags & FL_DUCKED) ? PMF_DUCKED : 0) |
+ (!(this.flags & FL_JUMPRELEASED) ? PMF_JUMP_HELD : 0) |
+ ((this.flags & FL_ONGROUND) ? PMF_ONGROUND : 0);
#endif
}
#define PHYS_INPUT_MOVEVALUES(s) input_movevalues
- #define PHYS_INPUT_BUTTON_MASK(s) (input_buttons | 128 * (input_movevalues_x < 0) | 256 * (input_movevalues_x > 0) | 512 * (input_movevalues_y < 0) | 1024 * (input_movevalues_y > 0))
- #define PHYS_INPUT_BUTTON_ATCK(s) !!(input_buttons & 1)
- #define PHYS_INPUT_BUTTON_JUMP(s) !!(input_buttons & 2)
- #define PHYS_INPUT_BUTTON_ATCK2(s) !!(input_buttons & 4)
- #define PHYS_INPUT_BUTTON_ZOOM(s) !!(input_buttons & 8)
- #define PHYS_INPUT_BUTTON_CROUCH(s) !!(input_buttons & 16)
- #define PHYS_INPUT_BUTTON_HOOK(s) !!(input_buttons & 32)
- #define PHYS_INPUT_BUTTON_USE(s) !!(input_buttons & 64)
- #define PHYS_INPUT_BUTTON_BACKWARD(s) !!(input_buttons & 128)
- #define PHYS_INPUT_BUTTON_FORWARD(s) !!(input_buttons & 256)
- #define PHYS_INPUT_BUTTON_LEFT(s) !!(input_buttons & 512)
- #define PHYS_INPUT_BUTTON_RIGHT(s) !!(input_buttons & 1024)
- #define PHYS_INPUT_BUTTON_JETPACK(s) !!(input_buttons & 4096)
+ #define PHYS_INPUT_BUTTON_MASK(s) (input_buttons | BIT(7) * (input_movevalues.x < 0) | BIT(8) * (input_movevalues.x > 0) | BIT(9) * (input_movevalues.y < 0) | BIT(10) * (input_movevalues.y > 0))
+ #define PHYS_INPUT_BUTTON_ATCK(s) boolean(input_buttons & BIT(0))
+ #define PHYS_INPUT_BUTTON_JUMP(s) boolean(input_buttons & BIT(1))
+ #define PHYS_INPUT_BUTTON_ATCK2(s) boolean(input_buttons & BIT(2))
+ #define PHYS_INPUT_BUTTON_ZOOM(s) boolean(input_buttons & BIT(3))
+ #define PHYS_INPUT_BUTTON_CROUCH(s) boolean(input_buttons & BIT(4))
+ #define PHYS_INPUT_BUTTON_HOOK(s) boolean(input_buttons & BIT(5))
+ #define PHYS_INPUT_BUTTON_USE(s) boolean(input_buttons & BIT(6))
+ #define PHYS_INPUT_BUTTON_BACKWARD(s) boolean(input_buttons & BIT(7))
+ #define PHYS_INPUT_BUTTON_FORWARD(s) boolean(input_buttons & BIT(8))
+ #define PHYS_INPUT_BUTTON_LEFT(s) boolean(input_buttons & BIT(9))
+ #define PHYS_INPUT_BUTTON_RIGHT(s) boolean(input_buttons & BIT(10))
+ #define PHYS_INPUT_BUTTON_JETPACK(s) boolean(input_buttons & BIT(12))
#define PHYS_DEAD(s) s.csqcmodel_isdead
#define GAMEPLAYFIX_NOGRAVITYONGROUND (boolean(moveflags & MOVEFLAG_NOGRAVITYONGROUND))
#define GAMEPLAYFIX_Q2AIRACCELERATE (boolean(moveflags & MOVEFLAG_Q2AIRACCELERATE))
- #define IS_DUCKED(s) !!(s.flags & FL_DUCKED)
+ #define IS_DUCKED(s) boolean(s.flags & FL_DUCKED)
#define SET_DUCKED(s) s.flags |= FL_DUCKED
#define UNSET_DUCKED(s) s.flags &= ~FL_DUCKED
#define SET_JUMP_HELD(s) s.flags &= ~FL_JUMPRELEASED
#define UNSET_JUMP_HELD(s) s.flags |= FL_JUMPRELEASED
- #define IS_ONGROUND(s) !!(s.flags & FL_ONGROUND)
+ #define IS_ONGROUND(s) boolean(s.flags & FL_ONGROUND)
#define SET_ONGROUND(s) s.flags |= FL_ONGROUND
#define UNSET_ONGROUND(s) s.flags &= ~FL_ONGROUND
- #define WAS_ONGROUND(s) !!(s.lastflags & FL_ONGROUND)
+ #define WAS_ONGROUND(s) boolean(s.lastflags & FL_ONGROUND)
#define ITEMS_STAT(s) (s).items
#define SET_JUMP_HELD(s) s.flags &= ~FL_JUMPRELEASED
#define UNSET_JUMP_HELD(s) s.flags |= FL_JUMPRELEASED
- #define IS_ONGROUND(s) !!(s.flags & FL_ONGROUND)
+ #define IS_ONGROUND(s) boolean(s.flags & FL_ONGROUND)
#define SET_ONGROUND(s) s.flags |= FL_ONGROUND
#define UNSET_ONGROUND(s) s.flags &= ~FL_ONGROUND
- #define WAS_ONGROUND(s) !!((s).lastflags & FL_ONGROUND)
+ #define WAS_ONGROUND(s) boolean((s).lastflags & FL_ONGROUND)
#define ITEMS_STAT(s) s.items
--- /dev/null
+#ifdef SVQC
+
+bool autocvar_bot_sound_monopoly;
+
+.entity realowner;
+bool sound_allowed(int to, entity e)
+{
+ for ( ; ; )
+ {
+ if (e.classname == "body") e = e.enemy;
+ else if (e.realowner && e.realowner != e) e = e.realowner;
+ else if (e.owner && e.owner != e) e = e.owner;
+ else break;
+ }
+ // sounds to self may always pass
+ if (to == MSG_ONE && e == msg_entity) return true;
+ // sounds by players can be removed
+ if (autocvar_bot_sound_monopoly && IS_REAL_CLIENT(e)) return false;
+ // anything else may pass
+ return true;
+}
+
+/** hack: string precache_sound(string s) = #19; */
+int precache_sound_index(string s) = #19;
+
+const int SVC_SOUND = 6;
+const int SVC_STOPSOUND = 16;
+
+const int SND_VOLUME = BIT(0);
+const int SND_ATTENUATION = BIT(1);
+const int SND_LARGEENTITY = BIT(3);
+const int SND_LARGESOUND = BIT(4);
+
+void soundtoat(int to, entity e, vector o, int chan, string samp, float vol, float attenu)
+{
+ if (!sound_allowed(to, e)) return;
+ int entno = etof(e);
+ int idx = precache_sound_index(samp);
+ attenu = floor(attenu * 64);
+ vol = floor(vol * 255);
+ int sflags = 0;
+ if (vol != 255) sflags |= SND_VOLUME;
+ if (attenu != 64) sflags |= SND_ATTENUATION;
+ if (entno >= 8192 || chan < 0 || chan > 7) sflags |= SND_LARGEENTITY;
+ if (idx >= 256) sflags |= SND_LARGESOUND;
+ WriteByte(to, SVC_SOUND);
+ WriteByte(to, sflags);
+ if (sflags & SND_VOLUME) WriteByte(to, vol);
+ if (sflags & SND_ATTENUATION) WriteByte(to, attenu);
+ if (sflags & SND_LARGEENTITY)
+ {
+ WriteShort(to, entno);
+ WriteByte(to, chan);
+ }
+ else
+ {
+ WriteShort(to, (entno << 3) | chan);
+ }
+ if (sflags & SND_LARGESOUND) WriteShort(to, idx);
+ else WriteByte(to, idx);
+ WriteCoord(to, o.x);
+ WriteCoord(to, o.y);
+ WriteCoord(to, o.z);
+}
+
+void soundto(int _dest, entity e, int chan, string samp, float vol, float _atten)
+{
+ if (!sound_allowed(_dest, e)) return;
+ vector o = e.origin + 0.5 * (e.mins + e.maxs);
+ soundtoat(_dest, e, o, chan, samp, vol, _atten);
+}
+void soundat(entity e, vector o, int chan, string samp, float vol, float _atten)
+{
+ soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, _atten);
+}
+void stopsoundto(int _dest, entity e, int chan)
+{
+ if (!sound_allowed(_dest, e)) return;
+ int entno = num_for_edict(e);
+ if (entno >= 8192 || chan < 0 || chan > 7)
+ {
+ int idx = precache_sound_index(SND(Null));
+ int sflags = SND_LARGEENTITY;
+ if (idx >= 256) sflags |= SND_LARGESOUND;
+ WriteByte(_dest, SVC_SOUND);
+ WriteByte(_dest, sflags);
+ WriteShort(_dest, entno);
+ WriteByte(_dest, chan);
+ if (sflags & SND_LARGESOUND) WriteShort(_dest, idx);
+ else WriteByte(_dest, idx);
+ WriteCoord(_dest, e.origin.x);
+ WriteCoord(_dest, e.origin.y);
+ WriteCoord(_dest, e.origin.z);
+ }
+ else
+ {
+ WriteByte(_dest, SVC_STOPSOUND);
+ WriteShort(_dest, entno * 8 + chan);
+ }
+}
+void stopsound(entity e, int chan)
+{
+ if (!sound_allowed(MSG_BROADCAST, e)) return;
+ stopsoundto(MSG_BROADCAST, e, chan); // unreliable, gets there fast
+ stopsoundto(MSG_ALL, e, chan); // in case of packet loss
+}
+
+void play2(entity e, string filename)
+{
+ msg_entity = e;
+ soundtoat(MSG_ONE, world, '0 0 0', CH_INFO, filename, VOL_BASE, ATTEN_NONE);
+}
+
+.float spamtime;
+/** use this one if you might be causing spam (e.g. from touch functions that might get called more than once per frame) */
+float spamsound(entity e, int chan, string samp, float vol, float _atten)
+{
+ if (!sound_allowed(MSG_BROADCAST, e)) return false;
+ if (time > e.spamtime)
+ {
+ e.spamtime = time;
+ _sound(e, chan, samp, vol, _atten);
+ return true;
+ }
+ return false;
+}
+
+void play2team(float t, string filename)
+{
+ if (autocvar_bot_sound_monopoly) return;
+ entity head;
+ FOR_EACH_REALPLAYER(head)
+ {
+ if (head.team == t) play2(head, filename);
+ }
+}
+
+void play2all(string samp)
+{
+ if (autocvar_bot_sound_monopoly) return;
+ _sound(world, CH_INFO, samp, VOL_BASE, ATTEN_NONE);
+}
+
+#endif
REGISTRY(Sounds, BITS(8))
#define Sounds_from(i) _Sounds_from(i, SND_Null)
-REGISTER_REGISTRY(RegisterSounds)
+REGISTER_REGISTRY(Sounds)
#define SOUND(name, path) \
string SND_##name##_get() { return path; } \
- REGISTER(RegisterSounds, SND, Sounds, name, m_id, NEW(Sound, SND_##name##_get))
+ REGISTER(Sounds, SND, name, m_id, NEW(Sound, SND_##name##_get))
// Used in places where a string is required
#define SND(id) Sound_fixpath(SND_##id)
SOUND(Null, "misc/null");
#include "all.inc"
-
+#include "all.qc"
#endif
#ifndef SOUND_H
#define SOUND_H
+// negative = SVQC autochannels
+// positive = one per entity
+
+const int CH_INFO = 0;
+const int CH_WEAPON_A = -1;
+const int CH_WEAPON_B = -1;
+const int CH_WEAPON_SINGLE = 1;
+const int CH_VOICE = -2;
+// const int CH_VOICE_SINGLE = 2;
+const int CH_TRIGGER = -3;
+const int CH_TRIGGER_SINGLE = 3;
+const int CH_SHOTS = -4;
+const int CH_SHOTS_SINGLE = 4;
+// const int CH_TUBA = -5;
+const int CH_TUBA_SINGLE = 5;
+const int CH_PAIN = -6;
+const int CH_PAIN_SINGLE = 6;
+const int CH_PLAYER = -7;
+const int CH_PLAYER_SINGLE = 7;
+// const int CH_BGM_SINGLE = -8;
+const int CH_BGM_SINGLE = 8;
+const int CH_AMBIENT = -9;
+// const int CH_AMBIENT_SINGLE = 9;
+
+const float ATTEN_NONE = 0;
+const float ATTEN_MIN = 0.015625;
+const float ATTEN_NORM = 0.5;
+const float ATTEN_LARGE = 1;
+const float ATTEN_IDLE = 2;
+const float ATTEN_STATIC = 3;
+const float ATTEN_MAX = 3.984375;
+
+const float VOL_BASE = 0.7;
+const float VOL_BASEVOICE = 1.0;
+
// Play all sounds via sound7, for access to the extra channels.
// Otherwise, channels 8 to 15 would be blocked for a weird QW feature.
#ifdef SVQC
#endif
#define sound(e, c, s, v, a) _sound(e, c, Sound_fixpath(s), v, a)
+/**
+ * because sound7 didn't have origin
+ *
+ * @param e sound owner
+ * @param o sound origin
+ * @param chan sound channel
+ * @param samp sound filename
+ * @param vol sound volume
+ * @param atten sound attenuation
+ * @param speed
+ * @param sf
+ */
+#define sound8(e, o, chan, samp, vol, atten, speed, sf) \
+ do \
+ { \
+ entity __e = e; \
+ vector old_origin = __e.origin; \
+ vector old_mins = __e.mins; \
+ vector old_maxs = __e.maxs; \
+ setorigin(__e, o); \
+ setsize(__e, '0 0 0', '0 0 0'); \
+ sound7(__e, chan, samp, vol, atten, speed, sf); \
+ setorigin(__e, old_origin); \
+ setsize(__e, old_mins, old_maxs); \
+ } \
+ while (0)
+
CLASS(Sound, Object)
ATTRIB(Sound, m_id, int, 0)
ATTRIB(Sound, sound_str, string(), func_null)
#define Sound_fixpath(this) _Sound_fixpath((this).sound_str())
string _Sound_fixpath(string base)
{
- if (base == "") return string_null;
- #define extensions(x) \
- x(wav) \
- x(ogg) \
- x(flac) \
- /**/
- string full, relative;
- #define tryext(ext) { if (fexists(full = strcat("sound/", relative = strcat(base, "." #ext)))) break; }
- do
- {
- extensions(tryext);
+ if (base == "") return string_null;
+ #define extensions(x) \
+ x(wav) \
+ x(ogg) \
+ x(flac) \
+ /**/
+ string full, relative;
+ #define tryext(ext) { if (fexists(full = strcat("sound/", relative = strcat(base, "." #ext)))) break; }
+ do
+ {
+ extensions(tryext);
#undef tryext
#undef extensions
- LOG_WARNINGF("Missing sound: \"%s\"\n", full);
- return string_null;
- }
- while (0);
- return relative;
+ LOG_WARNINGF("Missing sound: \"%s\"\n", full);
+ return string_null;
+ }
+ while (0);
+ return relative;
}
METHOD(Sound, sound_precache, void(entity this))
{
}
}
-void func_breakable_reset()
-{SELFPARAM();
- self.team = self.team_saved;
+void func_breakable_reset(entity this)
+{
+ this.team = this.team_saved;
func_breakable_look_restore();
- if(self.spawnflags & 1)
+ if(this.spawnflags & 1)
func_breakable_behave_destroyed();
else
func_breakable_behave_restore();
- CSQCMODEL_AUTOUPDATE(self);
+ CSQCMODEL_AUTOUPDATE(this);
}
// destructible walls that can be used to trigger target_objective_decrease
spawnfunc(func_breakable)
{
float n, i;
- if(!self.health)
- self.health = 100;
- self.max_health = self.health;
+ if(!this.health)
+ this.health = 100;
+ this.max_health = this.health;
// yes, I know, MOVETYPE_NONE is not available here, not that one would want it here anyway
- if(!self.debrismovetype) self.debrismovetype = MOVETYPE_BOUNCE;
- if(!self.debrissolid) self.debrissolid = SOLID_NOT;
- if(self.debrisvelocity == '0 0 0') self.debrisvelocity = '0 0 140';
- if(self.debrisvelocityjitter == '0 0 0') self.debrisvelocityjitter = '70 70 70';
- if(self.debrisavelocityjitter == '0 0 0') self.debrisavelocityjitter = '600 600 600';
- if(!self.debristime) self.debristime = 3.5;
- if(!self.debristimejitter) self.debristime = 2.5;
-
- if(self.mdl != "")
- self.cnt = _particleeffectnum(self.mdl);
- if(self.count == 0)
- self.count = 1;
-
- if(self.message == "")
- self.message = "got too close to an explosion";
- if(self.message2 == "")
- self.message2 = "was pushed into an explosion by";
- if(!self.dmg_radius)
- self.dmg_radius = 150;
- if(!self.dmg_force)
- self.dmg_force = 200;
-
- self.mdl = self.model;
+ if(!this.debrismovetype) this.debrismovetype = MOVETYPE_BOUNCE;
+ if(!this.debrissolid) this.debrissolid = SOLID_NOT;
+ if(this.debrisvelocity == '0 0 0') this.debrisvelocity = '0 0 140';
+ if(this.debrisvelocityjitter == '0 0 0') this.debrisvelocityjitter = '70 70 70';
+ if(this.debrisavelocityjitter == '0 0 0') this.debrisavelocityjitter = '600 600 600';
+ if(!this.debristime) this.debristime = 3.5;
+ if(!this.debristimejitter) this.debristime = 2.5;
+
+ if(this.mdl != "")
+ this.cnt = _particleeffectnum(this.mdl);
+ if(this.count == 0)
+ this.count = 1;
+
+ if(this.message == "")
+ this.message = "got too close to an explosion";
+ if(this.message2 == "")
+ this.message2 = "was pushed into an explosion by";
+ if(!this.dmg_radius)
+ this.dmg_radius = 150;
+ if(!this.dmg_force)
+ this.dmg_force = 200;
+
+ this.mdl = this.model;
SetBrushEntityModel();
- if(self.spawnflags & 4)
- self.use = func_breakable_destroy;
+ if(this.spawnflags & 4)
+ this.use = func_breakable_destroy;
else
- self.use = func_breakable_restore;
+ this.use = func_breakable_restore;
- if(self.spawnflags & 4)
+ if(this.spawnflags & 4)
{
- self.takedamage = DAMAGE_NO;
- self.event_damage = func_null;
- self.bot_attack = false;
+ this.takedamage = DAMAGE_NO;
+ this.event_damage = func_null;
+ this.bot_attack = false;
}
// precache all the models
- if (self.mdl_dead)
- precache_model(self.mdl_dead);
- n = tokenize_console(self.debris);
+ if (this.mdl_dead)
+ precache_model(this.mdl_dead);
+ n = tokenize_console(this.debris);
for(i = 0; i < n; ++i)
precache_model(argv(i));
- if(self.noise)
- precache_sound(self.noise);
- if(self.noise1)
- precache_sound(self.noise1);
+ if(this.noise)
+ precache_sound(this.noise);
+ if(this.noise1)
+ precache_sound(this.noise1);
- self.team_saved = self.team;
- self.dropped_origin = self.origin;
+ this.team_saved = this.team;
+ this.dropped_origin = this.origin;
- self.reset = func_breakable_reset;
- func_breakable_reset();
+ this.reset = func_breakable_reset;
+ this.reset(this);
- self.init_for_player_needed = 1;
- self.init_for_player = func_breakable_init_for_player;
+ this.init_for_player_needed = 1;
+ this.init_for_player = func_breakable_init_for_player;
- CSQCMODEL_AUTOINIT(self);
+ CSQCMODEL_AUTOINIT(this);
}
// for use in maps with a "model" key set
self.SendFlags |= 2;
}
-void conveyor_reset()
-{SELFPARAM();
- self.state = (self.spawnflags & 1);
+void conveyor_reset(entity this)
+{
+ this.state = (this.spawnflags & 1);
- self.SendFlags |= 2;
+ this.SendFlags |= 2;
}
bool conveyor_send(entity this, entity to, int sf)
void conveyor_init()
{SELFPARAM();
- if (!self.speed)
- self.speed = 200;
- self.movedir = self.movedir * self.speed;
- self.think = conveyor_think;
- self.nextthink = time;
+ if (!this.speed) this.speed = 200;
+ this.movedir *= this.speed;
+ this.think = conveyor_think;
+ this.nextthink = time;
IFTARGETED
{
- self.use = conveyor_use;
- self.reset = conveyor_reset;
- conveyor_reset();
+ this.use = conveyor_use;
+ this.reset = conveyor_reset;
+ this.reset(this);
}
else
- self.state = 1;
+ this.state = 1;
- FixSize(self);
+ FixSize(this);
- Net_LinkEntity(self, 0, false, conveyor_send);
+ Net_LinkEntity(this, 0, false, conveyor_send);
- self.SendFlags |= 1;
+ this.SendFlags |= 1;
}
spawnfunc(trigger_conveyor)
#endif
}
-void door_reset()
-{SELFPARAM();
- SUB_SETORIGIN(self, self.pos1);
- self.SUB_VELOCITY = '0 0 0';
- self.state = STATE_BOTTOM;
- self.SUB_THINK = func_null;
- self.SUB_NEXTTHINK = 0;
+void door_reset(entity this)
+{
+ SUB_SETORIGIN(this, this.pos1);
+ this.SUB_VELOCITY = '0 0 0';
+ this.state = STATE_BOTTOM;
+ this.SUB_THINK = func_null;
+ this.SUB_NEXTTHINK = 0;
#ifdef SVQC
- self.SendFlags |= SF_TRIGGER_RESET;
+ this.SendFlags |= SF_TRIGGER_RESET;
#endif
}
if(sf & SF_TRIGGER_INIT)
{
- self.classname = strzone(ReadString());
- self.spawnflags = ReadByte();
+ this.classname = strzone(ReadString());
+ this.spawnflags = ReadByte();
- self.mdl = strzone(ReadString());
- _setmodel(self, self.mdl);
+ this.mdl = strzone(ReadString());
+ _setmodel(this, this.mdl);
trigger_common_read(true);
- self.pos1_x = ReadCoord();
- self.pos1_y = ReadCoord();
- self.pos1_z = ReadCoord();
- self.pos2_x = ReadCoord();
- self.pos2_y = ReadCoord();
- self.pos2_z = ReadCoord();
-
- self.size_x = ReadCoord();
- self.size_y = ReadCoord();
- self.size_z = ReadCoord();
-
- self.wait = ReadShort();
- self.speed = ReadShort();
- self.lip = ReadByte();
- self.state = ReadByte();
- self.SUB_LTIME = ReadCoord();
-
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- self.trigger_touch = door_touch;
- self.draw = door_draw;
- self.drawmask = MASK_NORMAL;
- self.use = door_use;
+ vector v;
+
+ v.x = ReadCoord();
+ v.y = ReadCoord();
+ v.z = ReadCoord();
+ this.pos1 = v;
+
+ v.x = ReadCoord();
+ v.y = ReadCoord();
+ v.z = ReadCoord();
+ this.pos2 = v;
+
+ v.x = ReadCoord();
+ v.y = ReadCoord();
+ v.z = ReadCoord();
+ this.size = v;
+
+ this.wait = ReadShort();
+ this.speed = ReadShort();
+ this.lip = ReadByte();
+ this.state = ReadByte();
+ this.SUB_LTIME = ReadCoord();
+
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ this.trigger_touch = door_touch;
+ this.draw = door_draw;
+ this.drawmask = MASK_NORMAL;
+ this.use = door_use;
LinkDoors();
- if(self.spawnflags & DOOR_START_OPEN)
+ if(this.spawnflags & DOOR_START_OPEN)
door_init_startopen();
- self.move_time = time;
- self.move_origin = self.origin;
- self.move_movetype = MOVETYPE_PUSH;
- self.move_angles = self.angles;
- self.move_blocked = door_blocked;
+ this.move_time = time;
+ this.move_origin = this.origin;
+ this.move_movetype = MOVETYPE_PUSH;
+ this.move_angles = this.angles;
+ this.move_blocked = door_blocked;
}
if(sf & SF_TRIGGER_RESET)
{
- door_reset();
+ door_reset(this);
}
if(sf & SF_TRIGGER_UPDATE)
{
- self.origin_x = ReadCoord();
- self.origin_y = ReadCoord();
- self.origin_z = ReadCoord();
- setorigin(self, self.origin);
- self.move_origin = self.origin;
-
- self.pos1_x = ReadCoord();
- self.pos1_y = ReadCoord();
- self.pos1_z = ReadCoord();
- self.pos2_x = ReadCoord();
- self.pos2_y = ReadCoord();
- self.pos2_z = ReadCoord();
+ this.origin_x = ReadCoord();
+ this.origin_y = ReadCoord();
+ this.origin_z = ReadCoord();
+ setorigin(this, this.origin);
+ this.move_origin = this.origin;
+
+ this.pos1_x = ReadCoord();
+ this.pos1_y = ReadCoord();
+ this.pos1_z = ReadCoord();
+ this.pos2_x = ReadCoord();
+ this.pos2_y = ReadCoord();
+ this.pos2_z = ReadCoord();
}
return true;
}
FIXME: only one sound set available at the time being
*/
-void door_rotating_reset()
-{SELFPARAM();
- self.angles = self.pos1;
- self.avelocity = '0 0 0';
- self.state = STATE_BOTTOM;
- self.think = func_null;
- self.nextthink = 0;
+void door_rotating_reset(entity this)
+{
+ this.angles = this.pos1;
+ this.avelocity = '0 0 0';
+ this.state = STATE_BOTTOM;
+ this.think = func_null;
+ this.nextthink = 0;
}
void door_rotating_init_startopen()
}
}
-void secret_reset()
-{SELFPARAM();
- if (self.spawnflags&SECRET_YES_SHOOT)
+void secret_reset(entity this)
+{
+ if (this.spawnflags & SECRET_YES_SHOOT)
{
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
+ this.health = 10000;
+ this.takedamage = DAMAGE_YES;
}
- setorigin(self, self.oldorigin);
- self.think = func_null;
- self.SUB_NEXTTHINK = 0;
+ setorigin(this, this.oldorigin);
+ this.think = func_null;
+ this.SUB_NEXTTHINK = 0;
}
/*QUAKED spawnfunc_func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot
spawnfunc(func_door_secret)
{
- /*if (!self.deathtype) // map makers can override this
- self.deathtype = " got in the way";*/
+ /*if (!this.deathtype) // map makers can override this
+ this.deathtype = " got in the way";*/
- if (!self.dmg)
- self.dmg = 2;
+ if (!this.dmg) this.dmg = 2;
// Magic formula...
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.classname = "door";
- if (!InitMovingBrushTrigger())
- return;
- self.effects |= EF_LOWPRECISION;
-
- if(self.noise == "")
- self.noise = "misc/talk.wav";
- precache_sound(self.noise);
-
- self.touch = secret_touch;
- self.blocked = secret_blocked;
- self.speed = 50;
- self.use = fd_secret_use;
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
+ this.classname = "door";
+ if (!InitMovingBrushTrigger()) return;
+ this.effects |= EF_LOWPRECISION;
+
+ if (this.noise == "") this.noise = "misc/talk.wav";
+ precache_sound(this.noise);
+
+ this.touch = secret_touch;
+ this.blocked = secret_blocked;
+ this.speed = 50;
+ this.use = fd_secret_use;
IFTARGETED
{
}
else
- self.spawnflags |= SECRET_YES_SHOOT;
+ this.spawnflags |= SECRET_YES_SHOOT;
- if(self.spawnflags&SECRET_YES_SHOOT)
+ if (this.spawnflags & SECRET_YES_SHOOT)
{
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
- self.event_damage = fd_secret_damage;
+ this.health = 10000;
+ this.takedamage = DAMAGE_YES;
+ this.event_damage = fd_secret_damage;
}
- self.oldorigin = self.origin;
- if (!self.wait)
- self.wait = 5; // 5 seconds before closing
+ this.oldorigin = this.origin;
+ if (!this.wait) this.wait = 5; // seconds before closing
- self.reset = secret_reset;
- secret_reset();
+ this.reset = secret_reset;
+ this.reset(this);
}
#endif
spawnfunc(func_plat)
{
- if (self.sounds == 0)
- self.sounds = 2;
+ if (this.sounds == 0) this.sounds = 2;
- if(self.spawnflags & 4)
- self.dmg = 10000;
+ if (this.spawnflags & 4) this.dmg = 10000;
- if(self.dmg && (self.message == ""))
- self.message = "was squished";
- if(self.dmg && (self.message2 == ""))
- self.message2 = "was squished by";
+ if (this.dmg && (this.message == "")) this.message = "was squished";
+ if (this.dmg && (this.message2 == "")) this.message2 = "was squished by";
- if (self.sounds == 1)
+ if (this.sounds == 1)
{
precache_sound ("plats/plat1.wav");
precache_sound ("plats/plat2.wav");
- self.noise = "plats/plat1.wav";
- self.noise1 = "plats/plat2.wav";
+ this.noise = "plats/plat1.wav";
+ this.noise1 = "plats/plat2.wav";
}
- if (self.sounds == 2)
+ if (this.sounds == 2)
{
precache_sound ("plats/medplat1.wav");
precache_sound ("plats/medplat2.wav");
- self.noise = "plats/medplat1.wav";
- self.noise1 = "plats/medplat2.wav";
+ this.noise = "plats/medplat1.wav";
+ this.noise1 = "plats/medplat2.wav";
}
- if (self.sound1)
+ if (this.sound1)
{
- precache_sound (self.sound1);
- self.noise = self.sound1;
+ precache_sound (this.sound1);
+ this.noise = this.sound1;
}
- if (self.sound2)
+ if (this.sound2)
{
- precache_sound (self.sound2);
- self.noise1 = self.sound2;
+ precache_sound (this.sound2);
+ this.noise1 = this.sound2;
}
- self.mangle = self.angles;
- self.angles = '0 0 0';
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
- self.classname = "plat";
+ this.classname = "plat";
if (!InitMovingBrushTrigger())
return;
- self.effects |= EF_LOWPRECISION;
- setsize (self, self.mins , self.maxs);
+ this.effects |= EF_LOWPRECISION;
+ setsize (this, this.mins , this.maxs);
- self.blocked = plat_crush;
+ this.blocked = plat_crush;
- if (!self.speed)
- self.speed = 150;
- if (!self.lip)
- self.lip = 16;
- if (!self.height)
- self.height = self.size_z - self.lip;
+ if (!this.speed) this.speed = 150;
+ if (!this.lip) this.lip = 16;
+ if (!this.height) this.height = this.size.z - this.lip;
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- self.pos2_z = self.origin_z - self.height;
+ this.pos1 = this.origin;
+ this.pos2 = this.origin;
+ this.pos2_z = this.origin.z - this.height;
- self.reset = plat_reset;
- plat_reset();
+ this.reset = plat_reset;
+ this.reset(this);
- InitializeEntity(self, plat_delayedinit, INITPRIO_FINDTARGET);
+ InitializeEntity(this, plat_delayedinit, INITPRIO_FINDTARGET);
}
#elif defined(CSQC)
void plat_draw(entity this)
if(sf & SF_TRIGGER_INIT)
{
- self.platmovetype_start = ReadByte();
- self.platmovetype_turn = ReadByte();
- self.platmovetype_end = ReadByte();
- self.spawnflags = ReadByte();
+ this.platmovetype_start = ReadByte();
+ this.platmovetype_turn = ReadByte();
+ this.platmovetype_end = ReadByte();
+ this.spawnflags = ReadByte();
- self.model = strzone(ReadString());
- _setmodel(self, self.model);
+ this.model = strzone(ReadString());
+ _setmodel(this, this.model);
trigger_common_read(true);
- self.pos1_x = ReadCoord();
- self.pos1_y = ReadCoord();
- self.pos1_z = ReadCoord();
- self.pos2_x = ReadCoord();
- self.pos2_y = ReadCoord();
- self.pos2_z = ReadCoord();
+ this.pos1_x = ReadCoord();
+ this.pos1_y = ReadCoord();
+ this.pos1_z = ReadCoord();
+ this.pos2_x = ReadCoord();
+ this.pos2_y = ReadCoord();
+ this.pos2_z = ReadCoord();
- self.size_x = ReadCoord();
- self.size_y = ReadCoord();
- self.size_z = ReadCoord();
+ this.size_x = ReadCoord();
+ this.size_y = ReadCoord();
+ this.size_z = ReadCoord();
- self.mangle_x = ReadAngle();
- self.mangle_y = ReadAngle();
- self.mangle_z = ReadAngle();
+ this.mangle_x = ReadAngle();
+ this.mangle_y = ReadAngle();
+ this.mangle_z = ReadAngle();
- self.speed = ReadShort();
- self.height = ReadShort();
- self.lip = ReadByte();
- self.state = ReadByte();
+ this.speed = ReadShort();
+ this.height = ReadShort();
+ this.lip = ReadByte();
+ this.state = ReadByte();
- self.dmg = ReadShort();
+ this.dmg = ReadShort();
- self.classname = "plat";
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- self.drawmask = MASK_NORMAL;
- self.draw = plat_draw;
- self.use = plat_use;
- self.entremove = trigger_remove_generic;
+ this.classname = "plat";
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ this.drawmask = MASK_NORMAL;
+ this.draw = plat_draw;
+ this.use = plat_use;
+ this.entremove = trigger_remove_generic;
- plat_reset(); // also called here
+ plat_reset(this); // also called here
- self.move_movetype = MOVETYPE_PUSH;
- self.move_origin = self.origin;
- self.move_angles = self.angles;
- self.move_time = time;
+ this.move_movetype = MOVETYPE_PUSH;
+ this.move_origin = this.origin;
+ this.move_angles = this.angles;
+ this.move_time = time;
plat_spawn_inside_trigger();
}
if(sf & SF_TRIGGER_RESET)
{
- plat_reset();
+ plat_reset(this);
- self.move_origin = self.origin;
- self.move_angles = self.angles;
- self.move_time = time;
+ this.move_origin = this.origin;
+ this.move_angles = this.angles;
+ this.move_time = time;
}
return true;
}
self.nextthink = time;
}
-void pointparticles_reset()
-{SELFPARAM();
- if(self.spawnflags & 1)
- self.state = 1;
+void pointparticles_reset(entity this)
+{
+ if(this.spawnflags & 1)
+ this.state = 1;
else
- self.state = 0;
+ this.state = 0;
}
spawnfunc(func_pointparticles)
{
- if(self.model != "")
- _setmodel(self, self.model);
- if(self.noise != "")
- precache_sound (self.noise);
+ if(this.model != "") _setmodel(this, this.model);
+ if(this.noise != "") precache_sound(this.noise);
- if(!self.bgmscriptsustain)
- self.bgmscriptsustain = 1;
- else if(self.bgmscriptsustain < 0)
- self.bgmscriptsustain = 0;
+ if(!this.bgmscriptsustain) this.bgmscriptsustain = 1;
+ else if(this.bgmscriptsustain < 0) this.bgmscriptsustain = 0;
- if(!self.atten)
- self.atten = ATTEN_NORM;
- else if(self.atten < 0)
- self.atten = 0;
- if(!self.volume)
- self.volume = 1;
- if(!self.count)
- self.count = 1;
- if(!self.impulse)
- self.impulse = 1;
+ if(!this.atten) this.atten = ATTEN_NORM;
+ else if(this.atten < 0) this.atten = 0;
+ if(!this.volume) this.volume = 1;
+ if(!this.count) this.count = 1;
+ if(!this.impulse) this.impulse = 1;
- if(!self.modelindex)
+ if(!this.modelindex)
{
- setorigin(self, self.origin + self.mins);
- setsize(self, '0 0 0', self.maxs - self.mins);
+ setorigin(this, this.origin + this.mins);
+ setsize(this, '0 0 0', this.maxs - this.mins);
}
- if(!self.cnt)
- self.cnt = _particleeffectnum(self.mdl);
+ if(!this.cnt) this.cnt = _particleeffectnum(this.mdl);
- Net_LinkEntity(self, (self.spawnflags & 4), 0, pointparticles_SendEntity);
+ Net_LinkEntity(this, (this.spawnflags & 4), 0, pointparticles_SendEntity);
IFTARGETED
{
- self.use = pointparticles_use;
- self.reset = pointparticles_reset;
- self.reset();
+ this.use = pointparticles_use;
+ this.reset = pointparticles_reset;
+ this.reset(this);
}
else
- self.state = 1;
- self.think = pointparticles_think;
- self.nextthink = time;
+ this.state = 1;
+ this.think = pointparticles_think;
+ this.nextthink = time;
}
spawnfunc(func_sparks)
#if defined(CSQC)
- #include "../../buffs/all.qh"
#include "../../../lib/csqcmodel/interpolate.qh"
#include "../../../client/main.qh"
#include "../../../lib/csqcmodel/cl_model.qh"
misc_laser_aim();
}
-void laser_reset()
-{SELFPARAM();
- if(self.spawnflags & 1)
- self.state = 1;
+void laser_reset(entity this)
+{
+ if(this.spawnflags & 1)
+ this.state = 1;
else
- self.state = 0;
+ this.state = 0;
}
spawnfunc(misc_laser)
{
- if(self.mdl)
+ if(this.mdl)
{
- if(self.mdl == "none")
- self.cnt = -1;
+ if(this.mdl == "none")
+ this.cnt = -1;
else
{
- self.cnt = _particleeffectnum(self.mdl);
- if(self.cnt < 0)
- if(self.dmg)
- self.cnt = particleeffectnum(EFFECT_LASER_DEADLY);
+ this.cnt = _particleeffectnum(this.mdl);
+ if(this.cnt < 0 && this.dmg)
+ this.cnt = particleeffectnum(EFFECT_LASER_DEADLY);
}
}
- else if(!self.cnt)
+ else if(!this.cnt)
{
- if(self.dmg)
- self.cnt = particleeffectnum(EFFECT_LASER_DEADLY);
+ if(this.dmg)
+ this.cnt = particleeffectnum(EFFECT_LASER_DEADLY);
else
- self.cnt = -1;
+ this.cnt = -1;
}
- if(self.cnt < 0)
- self.cnt = -1;
+ if(this.cnt < 0)
+ this.cnt = -1;
- if(self.colormod == '0 0 0')
- if(!self.alpha)
- self.colormod = '1 0 0';
- if(self.message == "")
- self.message = "saw the light";
- if (self.message2 == "")
- self.message2 = "was pushed into a laser by";
- if(!self.scale)
- self.scale = 1;
- if(!self.modelscale)
- self.modelscale = 1;
- else if(self.modelscale < 0)
- self.modelscale = 0;
- self.think = misc_laser_think;
- self.nextthink = time;
- InitializeEntity(self, misc_laser_init, INITPRIO_FINDTARGET);
+ if(this.colormod == '0 0 0')
+ if(!this.alpha)
+ this.colormod = '1 0 0';
+ if(this.message == "") this.message = "saw the light";
+ if (this.message2 == "") this.message2 = "was pushed into a laser by";
+ if(!this.scale) this.scale = 1;
+ if(!this.modelscale) this.modelscale = 1;
+ else if(this.modelscale < 0) this.modelscale = 0;
+ this.think = misc_laser_think;
+ this.nextthink = time;
+ InitializeEntity(this, misc_laser_init, INITPRIO_FINDTARGET);
- self.mangle = self.angles;
+ this.mangle = this.angles;
- Net_LinkEntity(self, false, 0, laser_SendEntity);
+ Net_LinkEntity(this, false, 0, laser_SendEntity);
IFTARGETED
{
- self.reset = laser_reset;
- laser_reset();
- self.use = laser_use;
+ this.reset = laser_reset;
+ this.reset(this);
+ this.use = laser_use;
}
else
- self.state = 1;
+ this.state = 1;
}
#elif defined(CSQC)
{
if(!self.state)
return;
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(self);
if(self.count & 0x80)
{
if(self.count & 0x10)
NET_HANDLE(ENT_CLIENT_LASER, bool isnew)
{
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
// 30 bytes, or 13 bytes for just moving
int f = ReadByte();
return = true;
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
self.draw = Draw_Laser;
}
#endif
.string sound1, sound2;
-void plat_reset()
-{SELFPARAM();
+void plat_reset(entity this)
+{
IFTARGETED
{
- setorigin (self, self.pos1);
- self.state = 4;
- self.use = plat_use;
+ setorigin (this, this.pos1);
+ this.state = 4;
+ this.use = plat_use;
}
else
{
- setorigin (self, self.pos2);
- self.state = 2;
- self.use = plat_trigger_use;
+ setorigin (this, this.pos2);
+ this.state = 2;
+ this.use = plat_trigger_use;
}
#ifdef SVQC
- self.SendFlags |= SF_TRIGGER_RESET;
+ this.SendFlags |= SF_TRIGGER_RESET;
#endif
}
#endif
-void SUB_Remove();
void SUB_SetFade (entity ent, float when, float fading_time);
void SUB_VanishOrRemove (entity ent);
WriteByte(to, self.lifetime);
WriteString(to, self.noise);
}
-void target_music_reset()
-{SELFPARAM();
- if(self.targetname == "")
- target_music_sendto(MSG_ALL, 1);
+void target_music_reset(entity this)
+{
+ if (this.targetname == "") target_music_sendto(MSG_ALL, 1);
}
void target_music_kill()
{
}
return 1;
}
-void trigger_music_reset()
-{SELFPARAM();
- self.cnt = !(self.spawnflags & 1);
- self.SendFlags |= 0x80;
+void trigger_music_reset(entity this)
+{
+ this.cnt = !(this.spawnflags & 1);
+ this.SendFlags |= 0x80;
}
void trigger_music_use()
{SELFPARAM();
}
spawnfunc(trigger_music)
{
- if(self.model != "")
- _setmodel(self, self.model);
- if(!self.volume)
- self.volume = 1;
- if(!self.modelindex)
+ if(this.model != "") _setmodel(this, this.model);
+ if(!this.volume) this.volume = 1;
+ if(!this.modelindex)
{
- setorigin(self, self.origin + self.mins);
- setsize(self, '0 0 0', self.maxs - self.mins);
+ setorigin(this, this.origin + this.mins);
+ setsize(this, '0 0 0', this.maxs - this.mins);
}
- trigger_music_reset();
+ trigger_music_reset(this);
- self.use = trigger_music_use;
- self.reset = trigger_music_reset;
+ this.use = trigger_music_use;
+ this.reset = trigger_music_reset;
- Net_LinkEntity(self, false, 0, trigger_music_SendEntity);
+ Net_LinkEntity(this, false, 0, trigger_music_SendEntity);
}
#elif defined(CSQC)
+entity TargetMusic_list;
+STATIC_INIT(TargetMusic_list)
+{
+ TargetMusic_list = LL_NEW();
+}
+
void TargetMusic_Advance()
{
// run AFTER all the thinks!
- entity best, e;
- float vol, vol0;
- best = music_default;
- if(music_target && time < music_target.lifetime)
- best = music_target;
- if(music_trigger)
- best = music_trigger;
- for(e = world; (e = findfloat(e, enttype, NET_ENT_CLIENT_TRIGGER_MUSIC.m_id)); ) if(e.noise)
- {
- vol0 = e.lastvol;
- if(getsoundtime(e, CH_BGM_SINGLE) < 0)
- {
- vol0 = -1;
- }
- if(e == best)
+ entity best = music_default;
+ if (music_target && time < music_target.lifetime) best = music_target;
+ if (music_trigger) best = music_trigger;
+ LL_EACH(TargetMusic_list, it.noise, LAMBDA(
+ const float vol0 = (getsoundtime(it, CH_BGM_SINGLE) >= 0) ? it.lastvol : -1;
+ if (it == best)
{
// increase volume
- if(e.fade_time > 0)
- e.state = bound(0, e.state + frametime / e.fade_time, 1);
- else
- e.state = 1;
+ it.state = (it.fade_time > 0) ? bound(0, it.state + frametime / it.fade_time, 1) : 1;
}
else
{
// decrease volume
- if(e.fade_rate > 0)
- e.state = bound(0, e.state - frametime / e.fade_rate, 1);
- else
- e.state = 0;
+ it.state = (it.fade_rate > 0) ? bound(0, it.state - frametime / it.fade_rate, 1) : 0;
}
- vol = e.state * e.volume * autocvar_bgmvolume;
- if(vol != vol0)
+ const float vol = it.state * it.volume * autocvar_bgmvolume;
+ if (vol != vol0)
{
if(vol0 < 0)
- _sound(e, CH_BGM_SINGLE, e.noise, vol, ATTEN_NONE); // restart
+ _sound(it, CH_BGM_SINGLE, it.noise, vol, ATTEN_NONE); // restart
else
- _sound(e, CH_BGM_SINGLE, "", vol, ATTEN_NONE);
- e.lastvol = vol;
+ _sound(it, CH_BGM_SINGLE, "", vol, ATTEN_NONE);
+ it.lastvol = vol;
}
- }
+ ));
music_trigger = world;
-
- if(best)
- bgmtime = getsoundtime(best, CH_BGM_SINGLE);
- else
- bgmtime = gettime(GETTIME_CDTRACK);
+ bgmtime = (best) ? getsoundtime(best, CH_BGM_SINGLE) : gettime(GETTIME_CDTRACK);
}
NET_HANDLE(TE_CSQC_TARGET_MUSIC, bool isNew)
void Net_TargetMusic()
{
- int id = ReadShort();
- float vol = ReadByte() / 255.0;
- float fai = ReadByte() / 16.0;
- float fao = ReadByte() / 16.0;
- float tim = ReadByte();
- string noi = ReadString();
+ const int id = ReadShort();
+ const float vol = ReadByte() / 255.0;
+ const float fai = ReadByte() / 16.0;
+ const float fao = ReadByte() / 16.0;
+ const float tim = ReadByte();
+ const string noi = ReadString();
- entity e;
- for(e = world; (e = findfloat(e, enttype, NET_ENT_CLIENT_TRIGGER_MUSIC.m_id)); )
- {
- if(e.count == id)
- break;
- }
- if(!e)
+ entity e = NULL;
+ LL_EACH(TargetMusic_list, it.count == id, LAMBDA(e = it; break));
+ if (!e)
{
- e = spawn();
- e.enttype = NET_ENT_CLIENT_TRIGGER_MUSIC.m_id;
+ LL_PUSH(TargetMusic_list, e = new(TargetMusic));
+ make_pure(e);
e.count = id;
}
if(e.noise != noi)
sound(self, CH_TRIGGER_SINGLE, SND_Null, VOL_BASE * self.volume, self.atten);
self.use = target_speaker_use_on;
}
-void target_speaker_reset()
-{SELFPARAM();
- if(self.spawnflags & 1) // LOOPED_ON
+void target_speaker_reset(entity this)
+{
+ if(this.spawnflags & 1) // LOOPED_ON
{
- if(self.use == target_speaker_use_on)
+ if(this.use == target_speaker_use_on)
target_speaker_use_on();
}
- else if(self.spawnflags & 2)
+ else if(this.spawnflags & 2)
{
- if(self.use == target_speaker_use_off)
+ if(this.use == target_speaker_use_off)
target_speaker_use_off();
}
}
}
}
-void counter_reset()
-{SELFPARAM();
- self.count = self.cnt;
- multi_reset();
+void counter_reset(entity this)
+{
+ this.count = this.cnt;
+ multi_reset(this);
}
/*QUAKED spawnfunc_trigger_counter (.5 .5 .5) ? nomessage
self.nextthink = self.wait;
}
-void delay_reset()
-{SELFPARAM();
- self.think = func_null;
- self.nextthink = 0;
+void delay_reset(entity this)
+{
+ this.think = func_null;
+ this.nextthink = 0;
}
spawnfunc(trigger_delay)
SUB_UseTargets();
}
-void _spawnfunc_trigger_flipflop();
spawnfunc(trigger_flipflop)
{
- if(self.spawnflags & 1)
- self.state = 1;
- self.use = flipflop_use;
- self.reset = _spawnfunc_trigger_flipflop; // perfect resetter
+ if(this.spawnflags & 1)
+ this.state = 1;
+ this.use = flipflop_use;
+ this.reset = spawnfunc_trigger_flipflop; // perfect resetter
}
-void _spawnfunc_trigger_flipflop() { SELFPARAM(); spawnfunc_trigger_flipflop(this); }
#endif
remove(self);
}
-void _spawnfunc_trigger_gamestart();
+void self_spawnfunc_trigger_gamestart();
spawnfunc(trigger_gamestart)
{
- self.use = gamestart_use;
- self.reset2 = _spawnfunc_trigger_gamestart;
+ this.use = gamestart_use;
+ this.reset2 = self_spawnfunc_trigger_gamestart;
- if(self.wait)
+ if(this.wait)
{
- self.think = self.use;
- self.nextthink = game_starttime + self.wait;
+ this.think = this.use;
+ this.nextthink = game_starttime + this.wait;
}
else
- InitializeEntity(self, gamestart_use, INITPRIO_FINDTARGET);
+ InitializeEntity(this, gamestart_use, INITPRIO_FINDTARGET);
}
-void _spawnfunc_trigger_gamestart() { SELFPARAM(); spawnfunc_trigger_gamestart(this); }
+void self_spawnfunc_trigger_gamestart() { SELFPARAM(); spawnfunc_trigger_gamestart(this); }
#endif
void trigger_push_touch()
{SELFPARAM();
- if (self.active == ACTIVE_NOT)
+ if (this.active == ACTIVE_NOT)
return;
#ifdef SVQC
return;
#endif
- if(self.team)
- if(((self.spawnflags & 4) == 0) == (DIFF_TEAM(self, other)))
+ if(this.team)
+ if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, other)))
return;
EXACTTRIGGER_TOUCH;
- if(self.enemy)
+ if(this.enemy)
{
- other.velocity = trigger_push_calculatevelocity(other.origin, self.enemy, self.height);
+ other.velocity = trigger_push_calculatevelocity(other.origin, this.enemy, this.height);
other.move_velocity = other.velocity;
}
- else if(self.target)
+ else if(this.target)
{
entity e;
RandomSelection_Init();
- for(e = world; (e = find(e, targetname, self.target)); )
+ for(e = world; (e = find(e, targetname, this.target)); )
{
if(e.cnt)
RandomSelection_Add(e, 0, string_null, e.cnt, 1);
else
RandomSelection_Add(e, 0, string_null, 1, 1);
}
- other.velocity = trigger_push_calculatevelocity(other.origin, RandomSelection_chosen_ent, self.height);
+ other.velocity = trigger_push_calculatevelocity(other.origin, RandomSelection_chosen_ent, this.height);
other.move_velocity = other.velocity;
}
else
{
- other.velocity = self.movedir;
+ other.velocity = this.movedir;
other.move_velocity = other.velocity;
}
// reset tracking of oldvelocity for impact damage (sudden velocity changes)
other.oldvelocity = other.velocity;
- if(self.pushltime < time) // prevent "snorring" sound when a player hits the jumppad more than once
+ if(this.pushltime < time) // prevent "snorring" sound when a player hits the jumppad more than once
{
// flash when activated
Send_Effect(EFFECT_JUMPPAD, other.origin, other.velocity, 1);
- _sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
- self.pushltime = time + 0.2;
+ _sound (other, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
+ this.pushltime = time + 0.2;
}
if(IS_REAL_CLIENT(other) || IS_BOT_CLIENT(other))
{
bool found = false;
for(int i = 0; i < other.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
- if(other.(jumppadsused[i]) == self)
+ if(other.(jumppadsused[i]) == this)
found = true;
if(!found)
{
- other.(jumppadsused[other.jumppadcount % NUM_JUMPPADSUSED]) = self;
+ other.(jumppadsused[other.jumppadcount % NUM_JUMPPADSUSED]) = this;
other.jumppadcount = other.jumppadcount + 1;
}
if(IS_REAL_CLIENT(other))
{
- if(self.message)
- centerprint(other, self.message);
+ if(this.message)
+ centerprint(other, this.message);
}
else
other.lastteleporttime = time;
other.istypefrag = 0;
}
- if(self.enemy.target)
+ if(this.enemy.target)
{
activator = other;
- WITH(entity, self, self.enemy, SUB_UseTargets());
+ WITH(entity, self, this.enemy, SUB_UseTargets());
}
if (other.flags & FL_PROJECTILE)
UpdateCSQCProjectile(other);
}
- if (self.spawnflags & PUSH_ONCE)
+ if (this.spawnflags & PUSH_ONCE)
{
- self.touch = func_null;
- self.think = SUB_Remove;
- self.nextthink = time;
+ this.touch = func_null;
+ this.think = SUB_Remove_self;
+ this.nextthink = time;
}
#endif
}
}
trigger_push_link();
- defer(0.1, trigger_push_updatelink);
+ defer(self, 0.1, trigger_push_updatelink);
#endif
}
SUB_UseTargets();
}
-void monoflop_reset()
-{SELFPARAM();
- self.state = 0;
- self.nextthink = 0;
+void monoflop_reset(entity this)
+{
+ this.state = 0;
+ this.nextthink = 0;
}
spawnfunc(trigger_monoflop)
}
}
-void multi_reset()
-{SELFPARAM();
- if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
- self.touch = multi_touch;
- if (self.max_health)
+void multi_reset(entity this)
+{
+ if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
+ this.touch = multi_touch;
+ if (this.max_health)
{
- self.health = self.max_health;
- self.takedamage = DAMAGE_YES;
- self.solid = SOLID_BBOX;
+ this.health = this.max_health;
+ this.takedamage = DAMAGE_YES;
+ this.solid = SOLID_BBOX;
}
- self.think = func_null;
- self.nextthink = 0;
- self.team = self.team_saved;
+ this.think = func_null;
+ this.nextthink = 0;
+ this.team = this.team_saved;
}
/*QUAKED spawnfunc_trigger_multiple (.5 .5 .5) ? notouch
#ifdef SVQC
void multi_trigger();
-void multi_reset();
+void multi_reset(entity this);
spawnfunc(trigger_once);
#endif
#ifdef SVQC
-void _spawnfunc_trigger_relay();
/*QUAKED spawnfunc_trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages.
*/
spawnfunc(trigger_relay)
{
- self.use = SUB_UseTargets;
- self.reset = _spawnfunc_trigger_relay; // this spawnfunc resets fully
+ this.use = SUB_UseTargets;
+ this.reset = spawnfunc_trigger_relay; // this spawnfunc resets fully
}
-void _spawnfunc_trigger_relay() { SELFPARAM(); spawnfunc_trigger_relay(this); }
#endif
}
}
-void trigger_relay_teamcheck_reset()
-{SELFPARAM();
- self.team = self.team_saved;
+void trigger_relay_teamcheck_reset(entity this)
+{
+ this.team = this.team_saved;
}
spawnfunc(trigger_relay_teamcheck)
{
- self.team_saved = self.team;
- self.use = trigger_relay_teamcheck_use;
- self.reset = trigger_relay_teamcheck_reset;
+ this.team_saved = this.team;
+ this.use = trigger_relay_teamcheck_use;
+ this.reset = trigger_relay_teamcheck_reset;
}
#endif
REGISTRY(Turrets, BITS(5))
#define Turrets_from(i) _Turrets_from(i, TUR_Null)
#define get_turretinfo(i) Turrets_from(i)
-REGISTER_REGISTRY(RegisterTurrets)
+REGISTER_REGISTRY(Turrets)
REGISTRY_CHECK(Turrets)
const int TUR_FIRST = 1;
#define TUR_LAST (Turrets_COUNT - 1)
-#define REGISTER_TURRET(id, inst) REGISTER(RegisterTurrets, TUR, Turrets, id, m_id, inst)
+#define REGISTER_TURRET(id, inst) REGISTER(Turrets, TUR, id, m_id, inst)
REGISTER_TURRET(Null, NEW(Turret));
return true;
}
-void load_unit_settings(entity ent, float is_reload)
+void load_unit_settings(entity ent, bool is_reload)
{SELFPARAM();
string unitname = ent.netname;
string sbase;
}
void turrets_manager_think()
-{SELFPARAM();
- self.nextthink = time + 1;
+{
+ SELFPARAM();
+ this.nextthink = time + 1;
- entity e;
if (autocvar_g_turrets_reloadcvars == 1)
{
- e = nextent(world);
- while (e)
- {
- if (IS_TURRET(e))
- {
- load_unit_settings(e,1);
- Turret tur = get_turretinfo(self.m_id);
- tur.tr_think(tur);
- }
-
- e = nextent(e);
- }
- cvar_set("g_turrets_reloadcvars","0");
+ FOREACH_ENTITY(IS_TURRET(it), LAMBDA(
+ load_unit_settings(it, true);
+ Turret tur = get_turretinfo(it.m_id);
+ tur.tr_think(tur);
+ ));
+ cvar_set("g_turrets_reloadcvars", "0");
}
}
case ANIM_PAIN:
if(self.frame != ANIM_PAIN)
- defer(0.25, walker_setnoanim);
+ defer(self, 0.25, walker_setnoanim);
break;
case ANIM_MELEE:
if(self.frame != ANIM_MELEE)
{
- defer(0.41, walker_setnoanim);
- defer(0.21, walker_melee_do_dmg);
+ defer(self, 0.41, walker_setnoanim);
+ defer(self, 0.21, walker_melee_do_dmg);
}
movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
}
#ifdef TURRET_DEBUG
-void SUB_Remove();
void marker_think()
{SELFPARAM();
if(self.cnt)
string get_model_parameters_desc;
float get_model_parameters(string mod, float skn); // call with string_null to clear; skin -1 means mod is the filename of the txt file and is to be split
-vector vec2(vector v);
-
#ifndef MENUQC
vector NearestPointOnBox(entity box, vector org);
#endif
#define normal_or_gentle(normal, gentle) (GENTLE ? ((gentle != "") ? gentle : normal) : normal)
#endif
-vector vec3(float x, float y, float z);
-
#ifndef MENUQC
vector animfixfps(entity e, vector a, vector b);
#endif
REGISTRY(Vehicles, BITS(3))
#define Vehicles_from(i) _Vehicles_from(i, VEH_Null)
#define get_vehicleinfo(i) Vehicles_from(i)
-REGISTER_REGISTRY(RegisterVehicles)
+REGISTER_REGISTRY(Vehicles)
REGISTRY_CHECK(Vehicles)
const int VEH_FIRST = 1;
#define VEH_LAST (Vehicles_COUNT - 1)
/** If you register a new vehicle, make sure to add it to all.inc */
-#define REGISTER_VEHICLE(id, inst) REGISTER(RegisterVehicles, VEH, Vehicles, id, vehicleid, inst)
+#define REGISTER_VEHICLE(id, inst) REGISTER(Vehicles, VEH, id, vehicleid, inst)
#if defined(SVQC)
#include "sv_vehicles.qh"
proj.use = vehicles_projectile_explode;
proj.owner = self;
proj.realowner = _owner;
- proj.think = SUB_Remove;
+ proj.think = SUB_Remove_self;
proj.nextthink = time + 30;
if(_health)
if(ret.wp00 == veh)
{
ret.classname = "";
- ret.think = SUB_Remove;
+ ret.think = SUB_Remove_self;
ret.nextthink = time + 0.1;
if(ret.waypointsprite_attached)
//if(!PHYS_INPUT_BUTTON_CROUCH(self) && !IS_DUCKED(self))
#ifdef SVQC
//self.BUTTON_CROUCH = (oldmovement_x < 0);
- if(oldmovement_x < 0)
+ if (oldmovement.x < 0)
self.BUTTON_CROUCH = true;
#elif defined(CSQC)
- if(oldmovement_x < 0) { input_buttons |= 16; self.flags |= FL_DUCKED; } //else { input_buttons &= ~16; self.flags &= ~FL_DUCKED; }
+ if (oldmovement.x < 0)
+ {
+ input_buttons |= BIT(4);
+ self.flags |= FL_DUCKED;
+ }
+ //else { input_buttons &= ~16; self.flags &= ~FL_DUCKED; }
#endif
}
}
void viewloc_SetViewLocation()
{
entity view = CSQCModel_server2csqc(player_localentnum);
- if(!view) { return; }
+ if (!view) return;
//NOTE: the "cam_" cvars sould probably be changed out with a spawnflag or an entity key. I have it like this for my testing -- Player_2
if(view.viewloc && !wasfreed(view.viewloc) && view.viewloc.enemy && view.viewloc.goalentity)
{
#include "../../lib/warpzone/common.qh"
#include "../../lib/warpzone/client.qh"
#include "../util.qh"
- #include "../buffs/all.qh"
#include "../../client/autocvars.qh"
#include "../deathtypes/all.qh"
#include "../../lib/csqcmodel/interpolate.qh"
#include "../stats.qh"
#include "../teams.qh"
#include "../util.qh"
- #include "../buffs/all.qh"
#include "../monsters/all.qh"
#include "config.qh"
#include "../../server/weapons/csqcprojectile.qh"
// WEAPON PLUGIN SYSTEM
-WepSet WepSet_FromWeapon(int a) {
+WepSet _WepSet_FromWeapon(int a) {
a -= WEP_FIRST;
if (Weapons_MAX > 24)
if (a >= 24) {
// weapon sets
typedef vector WepSet;
-#define WEPSET(id) WepSet_FromWeapon(WEP_##id.m_id)
-WepSet WepSet_FromWeapon(int a);
#ifdef SVQC
void WriteWepSet(float dest, WepSet w);
#endif
REGISTRY(Weapons, 72) // Increase as needed. Can be up to 72.
#define Weapons_from(i) _Weapons_from(i, WEP_Null)
#define get_weaponinfo(i) Weapons_from(i)
-REGISTER_REGISTRY(RegisterWeapons)
+REGISTER_REGISTRY(Weapons)
STATIC_INIT(WeaponPickup) { FOREACH(Weapons, true, LAMBDA(it.m_pickup = NEW(WeaponPickup, it))); }
+.WepSet m_wepset;
+#define WEPSET(id) (WEP_##id.m_wepset)
+#define WepSet_FromWeapon(i) (Weapons_from(i).m_wepset)
+WepSet _WepSet_FromWeapon(int i);
+STATIC_INIT(WepSets)
+{
+ FOREACH(Weapons, true, LAMBDA(it.m_wepset = _WepSet_FromWeapon(it.m_id)));
+}
GENERIC_COMMAND(dumpweapons, "Dump all weapons into weapons_dump.txt") // WEAPONTODO: make this work with other progs than just server
{
#define REGISTER_WEAPON(id, inst) \
/* WepSet WEPSET_##id; */ \
- REGISTER(RegisterWeapons, WEP, Weapons, id, m_id, inst)
+ REGISTER(Weapons, WEP, id, m_id, inst)
// create cvars for weapon settings
#define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
{
FOREACH(Weapons, true, LAMBDA(
it.m_id = i;
- WepSet set = WepSet_FromWeapon(it.m_id);
+ WepSet set = it.m_wepset;
WEPSET_ALL |= set;
if ((it.spawnflags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= set;
it.weapon = it.m_id;
if(!self.beam_usevieworigin)
{
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(self);
}
// origin = beam starting origin
// self.iflags = IFLAG_ORIGIN | IFLAG_ANGLES | IFLAG_V_ANGLE; // why doesn't this work?
self.iflags = IFLAG_ORIGIN;
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
}
if(sf & ARC_SF_START) // starting location
else
{
// use player origin so that third person display still works
- self.origin = getplayerorigin(player_localnum) + ('0 0 1' * getstati(STAT_VIEWHEIGHT));
+ self.origin = entcs_receiver(player_localnum).origin + ('0 0 1' * getstati(STAT_VIEWHEIGHT));
}
}
if(!self.beam_usevieworigin)
{
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
}
return true;
}
void W_Blaster_Think()
{SELFPARAM();
- self.movetype = MOVETYPE_FLY;
- self.think = SUB_Remove;
- self.nextthink = time + self.blaster_lifetime;
- CSQCProjectile(self, true, PROJECTILE_BLASTER, true);
+ this.movetype = MOVETYPE_FLY;
+ this.think = SUB_Remove_self;
+ this.nextthink = time + this.blaster_lifetime;
+ CSQCProjectile(this, true, PROJECTILE_BLASTER, true);
}
void W_Blaster_Attack(
W_Crylink_Dequeue_Raw(e.realowner, e.queueprev, e, e.queuenext);
}
-void W_Crylink_Reset()
-{SELFPARAM();
- W_Crylink_Dequeue(self);
- remove(self);
+void W_Crylink_Reset(entity this)
+{
+ W_Crylink_Dequeue(this);
+ remove(this);
}
// force projectile to explode
//missile.angles = vectoangles(missile.velocity); // csqc
missile.touch = W_HLAC_Touch;
- missile.think = SUB_Remove;
+ missile.think = SUB_Remove_self;
missile.nextthink = time + WEP_CVAR_PRI(hlac, lifetime);
//missile.angles = vectoangles(missile.velocity); // csqc
missile.touch = W_HLAC_Touch;
- missile.think = SUB_Remove;
+ missile.think = SUB_Remove_self;
missile.nextthink = time + WEP_CVAR_SEC(hlac, lifetime);
void W_MachineGun_MuzzleFlash_Think()
{SELFPARAM();
- self.frame = self.frame + 2;
- self.scale = self.scale * 0.5;
- self.alpha = self.alpha - 0.25;
- self.nextthink = time + 0.05;
+ this.frame += 2;
+ this.scale *= 0.5;
+ this.alpha -= 0.25;
+ this.nextthink = time + 0.05;
- if(self.alpha <= 0)
+ if(this.alpha <= 0)
{
- self.think = SUB_Remove;
- self.nextthink = time;
- self.realowner.muzzle_flash = world;
+ this.think = SUB_Remove_self;
+ this.nextthink = time;
+ this.realowner.muzzle_flash = world;
return;
}
missile.bot_dodge = true;
missile.bot_dodgerating = 50;
missile.touch = W_Seeker_Tag_Touch;
- missile.think = SUB_Remove;
+ missile.think = SUB_Remove_self;
missile.nextthink = time + WEP_CVAR(seeker, tag_lifetime);
missile.movetype = MOVETYPE_FLY;
missile.solid = SOLID_BBOX;
// muzzle flash for 1st person view
flash = spawn();
setmodel(flash, MDL_SHOTGUN_MUZZLEFLASH); // precision set below
- flash.think = SUB_Remove;
+ flash.think = SUB_Remove_self;
flash.nextthink = time + 0.06;
flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
W_AttachToShotorg(self, flash, '5 0 0');
#endif
#endif
#ifdef IMPLEMENTATION
+
+REGISTER_NET_TEMP(TE_CSQC_VAPORBEAMPARTICLE)
+
+#if defined(SVQC)
+void SendCSQCVaporizerBeamParticle(entity player, int hit) {
+ vector v;
+ v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+ WriteHeader(MSG_BROADCAST, TE_CSQC_VAPORBEAMPARTICLE);
+ WriteCoord(MSG_BROADCAST, w_shotorg.x);
+ WriteCoord(MSG_BROADCAST, w_shotorg.y);
+ WriteCoord(MSG_BROADCAST, w_shotorg.z);
+ WriteCoord(MSG_BROADCAST, v.x);
+ WriteCoord(MSG_BROADCAST, v.y);
+ WriteCoord(MSG_BROADCAST, v.z);
+ WriteByte(MSG_BROADCAST, hit);
+ WriteShort(MSG_BROADCAST, num_for_edict(player));
+ WriteByte(MSG_BROADCAST, player.team);
+}
+#elif defined(CSQC)
+bool autocvar_cl_vaporizerbeam_particle = false;
+float autocvar_cl_vaporizerbeam_lifetime = 0.8;
+float autocvar_cl_vaporizerbeam_colorboost = 0.7;
+
+string Draw_VaporizerBeam_trace_callback_tex;
+float Draw_VaporizerBeam_trace_callback_rnd;
+vector Draw_VaporizerBeam_trace_callback_rgb;
+float Draw_VaporizerBeam_trace_callback_a;
+void Draw_VaporizerBeam_trace_callback(vector start, vector hit, vector end)
+{
+ float i;
+ vector vorg;
+ vorg = WarpZone_TransformOrigin(WarpZone_trace_transform, view_origin);
+ for(i = 0; i < Draw_VaporizerBeam_trace_callback_a; ++i)
+ Draw_CylindricLine(hit, start, 8, Draw_VaporizerBeam_trace_callback_tex, 0.25, Draw_VaporizerBeam_trace_callback_rnd, Draw_VaporizerBeam_trace_callback_rgb, min(1, Draw_VaporizerBeam_trace_callback_a - i), DRAWFLAG_NORMAL, vorg);
+ Draw_VaporizerBeam_trace_callback_rnd += 0.25 * vlen(hit - start) / 8;
+}
+
+.vector vorg1, vorg2;
+.float spawn_time;
+void VaporizerBeam_Draw(entity this)
+{
+ //draw either the old v2.3 beam or the new beam
+ particles_alphamin = particles_alphamax = particles_fade = 1;
+
+ string tex = "particles/lgbeam";
+ if(this.cnt)
+ tex = "particles/gauntletbeam";
+ vector rgb = getcsqcplayercolor(this.sv_entnum);
+ rgb *= (1 + autocvar_cl_vaporizerbeam_colorboost);
+
+ float fail = (self.nextthink - time);
+
+ Draw_VaporizerBeam_trace_callback_tex = tex;
+ Draw_VaporizerBeam_trace_callback_rnd = 0;
+ Draw_VaporizerBeam_trace_callback_rgb = rgb;
+ Draw_VaporizerBeam_trace_callback_a = bound(0, fail, 1);
+ WarpZone_TraceBox_ThroughZone(this.vorg1, '0 0 0', '0 0 0', this.vorg2, MOVE_NOTHING, world, world, Draw_VaporizerBeam_trace_callback);
+ Draw_VaporizerBeam_trace_callback_tex = string_null;
+
+ /*if(!MUTATOR_CALLHOOK(Particles_VaporizerBeam, this.vorg1, this.vorg2))
+ if(autocvar_cl_particles_oldvortexbeam && (getstati(STAT_ALLOW_OLDVORTEXBEAM) || isdemo()))
+ WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM_OLD), this.vorg1, this.vorg2, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
+ else
+ WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM), this.vorg1, this.vorg2, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);*/
+}
+
+NET_HANDLE(TE_CSQC_VAPORBEAMPARTICLE, bool isNew)
+{
+ Net_Accept(vortex_beam);
+ this.think = SUB_Remove_self;
+ this.nextthink = time + bound(0, autocvar_cl_vaporizerbeam_lifetime, 10);
+ this.draw = VaporizerBeam_Draw;
+ this.drawmask = MASK_NORMAL;
+
+ this.vorg1_x = ReadCoord(); this.vorg1_y = ReadCoord(); this.vorg1_z = ReadCoord();
+ this.vorg2_x = ReadCoord(); this.vorg2_y = ReadCoord(); this.vorg2_z = ReadCoord();
+ this.cnt = ReadByte();
+ this.sv_entnum = ReadShort();
+ this.team = ReadByte() - 1;
+
+ if(autocvar_cl_vaporizerbeam_particle)
+ {
+ WarpZone_TrailParticles(world, particleeffectnum(((this.cnt) ? EFFECT_VAPORIZER_HIT(this.team) : EFFECT_VAPORIZER(this.team))), this.vorg1, this.vorg2);
+ this.draw = func_null;
+ this.drawmask = MASK_NORMAL;
+ remove(this);
+ }
+
+ pointparticles(EFFECT_VORTEX_MUZZLEFLASH, this.vorg1, normalize(this.vorg2 - this.vorg1) * 1000, 1);
+ return true;
+}
+#endif
+
#ifdef SVQC
spawnfunc(weapon_vaporizer) { weapon_defaultspawnfunc(this, WEP_VAPORIZER); }
spawnfunc(weapon_minstanex) { spawnfunc_weapon_vaporizer(this); }
damage_goodhits = 0;
FireRailgunBullet(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, vaporizer_damage, 800, 0, 0, 0, 0, WEP_VAPORIZER.m_id);
+ // do this now, as goodhits is disabled below
+ SendCSQCVaporizerBeamParticle(self, damage_goodhits);
+
if(yoda && flying)
Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
if(damage_goodhits && self.vaporizer_lasthit)
self.vaporizer_lasthit = damage_goodhits;
- Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
- // teamcolor / hit beam effect
- vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
- Send_Effect((damage_goodhits ? EFFECT_VAPORIZER_HIT(self.team) : EFFECT_VAPORIZER(self.team)), w_shotorg, v, 1);
-
if(autocvar_g_rm)
if(!(trace_dphitq3surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NOIMPACT)))
W_RocketMinsta_Explosion(trace_endpos);
charge = sqrt(charge); // divide evenly among trail spacing and alpha
particles_alphamin = particles_alphamax = particles_fade = charge;
- if (autocvar_cl_particles_oldvortexbeam && (STAT(ALLOW_OLDVORTEXBEAM) || isdemo()))
+ if(!MUTATOR_CALLHOOK(Particles_VortexBeam, shotorg, endpos))
+ if(autocvar_cl_particles_oldvortexbeam && (STAT(ALLOW_OLDVORTEXBEAM) || isdemo()))
WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM_OLD), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
else
WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
#pragma noref 0
-#define ReadFloat() ReadCoord()
-
#endif
#pragma noref 0
-#define WriteFloat(to, f) WriteCoord(to, f)
-
#endif
#include "warpzone/mathlib.qc"
#include "accumulate.qh"
+#include "arraylist.qh"
#include "bits.qh"
#include "bool.qh"
#include "color.qh"
--- /dev/null
+#ifndef ARRAYLIST_H
+#define ARRAYLIST_H
+
+typedef int ArrayList;
+
+#define AL_declare(this) ArrayList this; int this##_len = (0)
+#define AL_init(this, n, default, T) \
+ do \
+ { \
+ this = buf_create(); \
+ this##_len = n; \
+ for (int i = 0; i < this##_len; ++i) \
+ { \
+ const _AL_type__##T() it = default; \
+ AL_set##T(this, i, it); \
+ } \
+ } \
+ while (0)
+
+#define _AL_type__s() string
+#define AL_gets(this, idx) bufstr_get(this, idx)
+#define AL_sets(this, idx, val) bufstr_set(this, idx, val)
+
+#define _AL_type__f() float
+#define AL_getf(this, idx) stof(AL_gets(this, idx))
+#define AL_setf(this, idx, val) AL_sets(this, idx, ftos(val))
+
+#define _AL_type__e() entity
+#define AL_gete(this, idx) ftoe(AL_getf(this, idx))
+#define AL_sete(this, idx, val) AL_setf(this, idx, etof(val))
+
+#define AL_EACH(this, T, cond, body) \
+ do \
+ { \
+ const noref ArrayList _al = this; \
+ for (int i = 0, n = this##_len; i < n; ++i) \
+ { \
+ const noref _AL_type__##T() it = AL_get##T(_al, i); \
+ if (cond) { body } \
+ } \
+ } \
+ while (0)
+
+#endif
// we don't do this for the local player as that one is already handled
// by CSQCPlayer_SetCamera()
- if(!CSQCPlayer_IsLocalPlayer())
- InterpolateOrigin_Do();
+ if (!CSQCPlayer_IsLocalPlayer(this)) InterpolateOrigin_Do(this);
CSQCModel_InterpolateAnimation_Do();
self.csqcmodel_teleported = 0;
}
+entity CSQCModel_players[255]; // 255 is engine limit on maxclients
+
+void CSQCModel_remove()
+{
+ SELFPARAM();
+ CSQCModel_players[this.entnum - 1] = NULL;
+}
+
NET_HANDLE(ENT_CLIENT_MODEL, bool isnew)
{
int sf = ReadInt24_t();
// some nice flags for CSQCMODEL_IF and the hooks
- bool isplayer = (self.entnum >= 1 && self.entnum <= maxclients);
- bool islocalplayer = (self.entnum == player_localnum + 1);
- noref bool isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1));
+ bool isplayer = (this.entnum >= 1 && this.entnum <= maxclients);
+ if (isnew && isplayer)
+ {
+ CSQCModel_players[this.entnum - 1] = this;
+ this.entremove = CSQCModel_remove;
+ }
+ bool islocalplayer = (this.entnum == player_localnum + 1);
+ noref bool isnolocalplayer = (isplayer && (this.entnum != player_localnum + 1));
- self.classname = "csqcmodel";
- self.iflags |= IFLAG_ORIGIN; // interpolate origin too
- self.iflags |= IFLAG_ANGLES; // interpolate angles too
- self.iflags |= IFLAG_VELOCITY | IFLAG_AUTOVELOCITY; // let's calculate velocity automatically
+ this.classname = "csqcmodel";
+ this.iflags |= IFLAG_ORIGIN; // interpolate origin too
+ this.iflags |= IFLAG_ANGLES; // interpolate angles too
+ this.iflags |= IFLAG_VELOCITY | IFLAG_AUTOVELOCITY; // let's calculate velocity automatically
{ CSQCMODEL_HOOK_PREUPDATE }
- CSQCPlayer_PreUpdate();
- InterpolateOrigin_Undo();
+ CSQCPlayer_PreUpdate(this);
+ InterpolateOrigin_Undo(this);
CSQCModel_InterpolateAnimation_PreNote(sf);
#define CSQCMODEL_IF(cond) if(cond) {
#define CSQCMODEL_ENDIF }
#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
if(sf & flag) \
- self.f = r();
+ this.f = r();
#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \
if(sf & flag) \
- self.f = (r() + mi) / s;
+ this.f = (r() + mi) / s;
ALLPROPERTIES
#undef CSQCMODEL_PROPERTY_SCALED
#undef CSQCMODEL_PROPERTY
if(sf & CSQCMODEL_PROPERTY_MODELINDEX)
{
- vector pmin = self.mins, pmax = self.maxs;
- setmodelindex(self, self.modelindex); // this retrieves the .model key and sets mins/maxs/absmin/absmax
- setsize(self, pmin, pmax);
+ vector pmin = this.mins, pmax = this.maxs;
+ setmodelindex(this, this.modelindex); // this retrieves the .model key and sets mins/maxs/absmin/absmax
+ setsize(this, pmin, pmax);
}
if(sf & CSQCMODEL_PROPERTY_TELEPORTED)
{
- self.iflags |= IFLAG_TELEPORTED;
- self.csqcmodel_teleported = 1;
+ this.iflags |= IFLAG_TELEPORTED;
+ this.csqcmodel_teleported = 1;
}
CSQCModel_InterpolateAnimation_Note(sf);
- InterpolateOrigin_Note();
- CSQCPlayer_PostUpdate();
+ InterpolateOrigin_Note(this);
+ CSQCPlayer_PostUpdate(this);
{ CSQCMODEL_HOOK_POSTUPDATE }
#ifdef CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(this);
CSQCModel_InterpolateAnimation_Do();
#endif
// relink
- setorigin(self, self.origin);
+ setorigin(this, this.origin);
// set obvious render flags
- if(self.entnum == player_localentnum)
- self.renderflags |= RF_EXTERNALMODEL;
+ if(this.entnum == player_localentnum)
+ this.renderflags |= RF_EXTERNALMODEL;
else
- self.renderflags &= ~RF_EXTERNALMODEL;
+ this.renderflags &= ~RF_EXTERNALMODEL;
// draw it
- self.drawmask = MASK_NORMAL;
- self.predraw = CSQCModel_Draw;
+ this.drawmask = MASK_NORMAL;
+ this.predraw = CSQCModel_Draw;
return true;
}
-entity CSQCModel_server2csqc(float pl)
+entity CSQCModel_server2csqc(int pl)
{
- return findfloat(world, entnum, pl); // FIXME optimize this using an array
+ if (pl <= maxclients) return CSQCModel_players[pl - 1];
+ LOG_WARNINGF("player out of bounds: %d\n", pl);
+ return findfloat(NULL, entnum, pl);
}
vector CSQCPlayer_GetPredictionErrorO()
{
- if(time >= csqcplayer_predictionerrortime)
- return '0 0 0';
+ if (time >= csqcplayer_predictionerrortime) return '0 0 0';
return csqcplayer_predictionerroro * (csqcplayer_predictionerrortime - time) * csqcplayer_predictionerrorfactor;
}
vector CSQCPlayer_GetPredictionErrorV()
{
- if(time >= csqcplayer_predictionerrortime)
- return '0 0 0';
+ if (time >= csqcplayer_predictionerrortime) return '0 0 0';
return csqcplayer_predictionerrorv * (csqcplayer_predictionerrortime - time) * csqcplayer_predictionerrorfactor;
}
csqcplayer_predictionerrortime = time + 1.0 / csqcplayer_predictionerrorfactor;
}
-void CSQCPlayer_Unpredict()
-{SELFPARAM();
- if(csqcplayer_status == CSQCPLAYERSTATUS_UNPREDICTED)
- return;
- if(csqcplayer_status != CSQCPLAYERSTATUS_PREDICTED)
- error("Cannot unpredict in current status");
- self.origin = csqcplayer_origin;
- self.velocity = csqcplayer_velocity;
- csqcplayer_moveframe = csqcplayer_sequence+1; //+1 because the recieved frame has the move already done (server side)
- self.flags = player_pmflags;
+void CSQCPlayer_Unpredict(entity this)
+{
+ if (csqcplayer_status == CSQCPLAYERSTATUS_UNPREDICTED) return;
+ if (csqcplayer_status != CSQCPLAYERSTATUS_PREDICTED) LOG_FATALF("Cannot unpredict in current status (%d)\n", csqcplayer_status);
+ this.origin = csqcplayer_origin;
+ this.velocity = csqcplayer_velocity;
+ csqcplayer_moveframe = csqcplayer_sequence + 1; // + 1 because the recieved frame has the move already done (server side)
+ this.flags = player_pmflags;
}
-void CSQCPlayer_SetMinsMaxs()
-{SELFPARAM();
- if(self.flags & FL_DUCKED)
+void CSQCPlayer_SetMinsMaxs(entity this)
+{
+ if (this.flags & FL_DUCKED)
{
- self.mins = PL_CROUCH_MIN;
- self.maxs = PL_CROUCH_MAX;
- self.view_ofs = PL_CROUCH_VIEW_OFS;
+ this.mins = PL_CROUCH_MIN;
+ this.maxs = PL_CROUCH_MAX;
+ this.view_ofs = PL_CROUCH_VIEW_OFS;
}
else
{
- self.mins = PL_MIN;
- self.maxs = PL_MAX;
- self.view_ofs = PL_VIEW_OFS;
+ this.mins = PL_MIN;
+ this.maxs = PL_MAX;
+ this.view_ofs = PL_VIEW_OFS;
}
}
-void CSQCPlayer_SavePrediction()
-{SELFPARAM();
- player_pmflags = self.flags;
- csqcplayer_origin = self.origin;
- csqcplayer_velocity = self.velocity;
+void CSQCPlayer_SavePrediction(entity this)
+{
+ player_pmflags = this.flags;
+ csqcplayer_origin = this.origin;
+ csqcplayer_velocity = this.velocity;
csqcplayer_sequence = servercommandframe;
csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
}
-void CSQC_ClientMovement_PlayerMove_Frame();
+void CSQC_ClientMovement_PlayerMove_Frame(entity this);
-void PM_Movement_Move()
-{SELFPARAM();
- runstandardplayerphysics(self);
+void PM_Movement_Move(entity this)
+{
+ runstandardplayerphysics(this);
#ifdef CSQC
- self.flags =
- ((self.pmove_flags & PMF_DUCKED) ? FL_DUCKED : 0) |
- (!(self.pmove_flags & PMF_JUMP_HELD) ? FL_JUMPRELEASED : 0) |
- ((self.pmove_flags & PMF_ONGROUND) ? FL_ONGROUND : 0);
+ this.flags =
+ ((this.pmove_flags & PMF_DUCKED) ? FL_DUCKED : 0) |
+ (!(this.pmove_flags & PMF_JUMP_HELD) ? FL_JUMPRELEASED : 0) |
+ ((this.pmove_flags & PMF_ONGROUND) ? FL_ONGROUND : 0);
#endif
}
-void CSQCPlayer_Physics()
+void CSQCPlayer_Physics(entity this)
{
- switch(autocvar_cl_movement)
+ switch (autocvar_cl_movement)
{
- case 1: CSQC_ClientMovement_PlayerMove_Frame(); break;
- case 2: PM_Movement_Move(); break;
+ case 1: CSQC_ClientMovement_PlayerMove_Frame(this); break;
+ case 2: PM_Movement_Move(this); break;
}
}
-void CSQCPlayer_PredictTo(float endframe, float apply_error)
-{SELFPARAM();
- CSQCPlayer_Unpredict();
- if(apply_error)
+void CSQCPlayer_PredictTo(entity this, float endframe, bool apply_error)
+{
+ CSQCPlayer_Unpredict(this);
+ if (apply_error)
{
- self.origin += CSQCPlayer_GetPredictionErrorO();
- self.velocity += CSQCPlayer_GetPredictionErrorV();
+ this.origin += CSQCPlayer_GetPredictionErrorO();
+ this.velocity += CSQCPlayer_GetPredictionErrorV();
}
- CSQCPlayer_SetMinsMaxs();
+ CSQCPlayer_SetMinsMaxs(this);
csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
}
#endif
- if(csqcplayer_moveframe >= endframe)
+ if (csqcplayer_moveframe >= endframe)
{
getinputstate(csqcplayer_moveframe - 1);
}
{
do
{
- if (!getinputstate(csqcplayer_moveframe))
- break;
- CSQCPlayer_Physics();
- CSQCPlayer_SetMinsMaxs();
- csqcplayer_moveframe++;
+ if (!getinputstate(csqcplayer_moveframe)) break;
+ CSQCPlayer_Physics(this);
+ CSQCPlayer_SetMinsMaxs(this);
+ ++csqcplayer_moveframe;
}
- while(csqcplayer_moveframe < endframe);
+ while (csqcplayer_moveframe < endframe);
}
- //add in anything that was applied after (for low packet rate protocols)
+ // add in anything that was applied after (for low packet rate protocols)
input_angles = view_angles;
}
-bool CSQCPlayer_IsLocalPlayer()
-{SELFPARAM();
- return (self == csqcplayer);
+bool CSQCPlayer_IsLocalPlayer(entity this)
+{
+ return (this == csqcplayer);
}
void CSQCPlayer_SetViewLocation()
viewloc_SetViewLocation();
}
+/** Called once per CSQC_UpdateView() */
void CSQCPlayer_SetCamera()
-{SELFPARAM();
- vector v0;
- v0 = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity
-
- if(csqcplayer)
+{
+ const vector v0 = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity
+ const float vh = getstati(STAT_VIEWHEIGHT);
+ const vector pl_viewofs = PL_VIEW_OFS;
+ const vector pl_viewofs_crouch = PL_CROUCH_VIEW_OFS;
+ const entity e = csqcplayer;
+ if (e)
{
- setself(csqcplayer);
-
- if(servercommandframe == 0 || clientcommandframe == 0)
+ if (servercommandframe == 0 || clientcommandframe == 0)
{
- InterpolateOrigin_Do();
- self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
+ InterpolateOrigin_Do(e);
+ e.view_ofs = '0 0 1' * vh;
// get crouch state from the server
- if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
- self.flags &= ~FL_DUCKED;
- else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
- self.flags |= FL_DUCKED;
+ if (vh == pl_viewofs.z) e.flags &= ~FL_DUCKED;
+ else if (vh == pl_viewofs_crouch.z) e.flags |= FL_DUCKED;
// get onground state from the server
- if(pmove_onground)
- self.flags |= FL_ONGROUND;
- else
- self.flags &= ~FL_ONGROUND;
+ e.flags = BITSET(e.flags, FL_ONGROUND, pmove_onground);
- CSQCPlayer_SetMinsMaxs();
+ CSQCPlayer_SetMinsMaxs(e);
// override it back just in case
- self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
+ e.view_ofs = '0 0 1' * vh;
// set velocity
- self.velocity = v0;
+ e.velocity = v0;
}
else
{
- float flg = self.iflags;
- self.iflags &= ~(IFLAG_ORIGIN | IFLAG_ANGLES);
- InterpolateOrigin_Do();
- self.iflags = flg;
+ const int flg = e.iflags; e.iflags &= ~(IFLAG_ORIGIN | IFLAG_ANGLES);
+ InterpolateOrigin_Do(e);
+ e.iflags = flg;
- if(csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER)
+ if (csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER)
{
- vector o, v;
- o = self.origin;
- v = v0;
+ const vector o = e.origin;
csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
- CSQCPlayer_PredictTo(servercommandframe + 1, false);
- CSQCPlayer_SetPredictionError(self.origin - o, self.velocity - v, pmove_onground - !!(self.flags & FL_ONGROUND));
- self.origin = o;
- self.velocity = v;
+ CSQCPlayer_PredictTo(e, servercommandframe + 1, false);
+ CSQCPlayer_SetPredictionError(e.origin - o, e.velocity - v0, pmove_onground - boolean(e.flags & FL_ONGROUND));
+ e.origin = o;
+ e.velocity = v0;
// get crouch state from the server
- if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
- self.flags &= ~FL_DUCKED;
- else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
- self.flags |= FL_DUCKED;
+ if (vh == pl_viewofs.z) e.flags &= ~FL_DUCKED;
+ else if(vh == pl_viewofs_crouch.z) e.flags |= FL_DUCKED;
// get onground state from the server
- if(pmove_onground)
- self.flags |= FL_ONGROUND;
- else
- self.flags &= ~FL_ONGROUND;
+ e.flags = BITSET(e.flags, FL_ONGROUND, pmove_onground);
- CSQCPlayer_SavePrediction();
+ CSQCPlayer_SavePrediction(e);
}
- CSQCPlayer_PredictTo(clientcommandframe + 1, true);
+ CSQCPlayer_PredictTo(e, clientcommandframe + 1, true);
#ifdef CSQCMODEL_SERVERSIDE_CROUCH
// get crouch state from the server (LAG)
- if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
- self.flags &= ~FL_DUCKED;
- else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
- self.flags |= FL_DUCKED;
+ if (vh == pl_viewofs.z) e.flags &= ~FL_DUCKED;
+ else if (vh == pl_viewofs_crouch.z) e.flags |= FL_DUCKED;
#endif
+ CSQCPlayer_SetMinsMaxs(e);
- CSQCPlayer_SetMinsMaxs();
-
- self.angles_y = input_angles.y;
+ e.angles_y = input_angles.y;
}
// relink
- setorigin(self, self.origin);
-
- setself(this);
- }
-
- entity view = CSQCModel_server2csqc(player_localentnum);
-
- if(view && view != csqcplayer)
- {
- WITH(entity, self, view, InterpolateOrigin_Do());
- view.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
+ setorigin(e, e.origin);
}
- if(view)
+ const entity view = CSQCModel_server2csqc(player_localentnum);
+ if (view)
{
+ if (view != csqcplayer)
+ {
+ InterpolateOrigin_Do(view);
+ view.view_ofs = '0 0 1' * vh;
+ }
int refdefflags = 0;
-
- if(view.csqcmodel_teleported)
- refdefflags |= REFDEFFLAG_TELEPORTED;
-
- if(input_buttons & 4)
- refdefflags |= REFDEFFLAG_JUMPING;
-
+ if (view.csqcmodel_teleported) refdefflags |= REFDEFFLAG_TELEPORTED;
+ if (input_buttons & BIT(1)) refdefflags |= REFDEFFLAG_JUMPING;
// note: these two only work in WIP2, but are harmless in WIP1
- if(getstati(STAT_HEALTH) <= 0)
- refdefflags |= REFDEFFLAG_DEAD;
-
- if(intermission)
- refdefflags |= REFDEFFLAG_INTERMISSION;
-
+ if (getstati(STAT_HEALTH) <= 0) refdefflags |= REFDEFFLAG_DEAD;
+ if (intermission) refdefflags |= REFDEFFLAG_INTERMISSION;
V_CalcRefdef(view, refdefflags);
}
else
// FIXME by CSQC spec we have to do this:
// but it breaks chase cam
/*
- setproperty(VF_ORIGIN, pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT));
+ setproperty(VF_ORIGIN, pmove_org + '0 0 1' * vh);
setproperty(VF_ANGLES, view_angles);
*/
}
-
- { CSQCPLAYER_HOOK_POSTCAMERASETUP }
+ CSQCPLAYER_HOOK_POSTCAMERASETUP();
}
void CSQCPlayer_Remove()
{
- csqcplayer = world;
+ csqcplayer = NULL;
cvar_settemp("cl_movement_replay", "1");
}
-float CSQCPlayer_PreUpdate()
-{SELFPARAM();
- if(self != csqcplayer)
- return 0;
- if(csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER)
- CSQCPlayer_Unpredict();
- return 1;
+bool CSQCPlayer_PreUpdate(entity this)
+{
+ if (this != csqcplayer) return false;
+ if (csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER) CSQCPlayer_Unpredict(this);
+ return true;
}
-float CSQCPlayer_PostUpdate()
-{SELFPARAM();
- if(self.entnum != player_localnum + 1)
- return 0;
- csqcplayer = self;
+bool CSQCPlayer_PostUpdate(entity this)
+{
+ if (this.entnum != player_localnum + 1) return false;
+ csqcplayer = this;
csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER;
cvar_settemp("cl_movement_replay", "0");
- self.entremove = CSQCPlayer_Remove;
- return 1;
+ this.entremove = CSQCPlayer_Remove;
+ return true;
}
const int FL_DUCKED = 524288;
void CSQCPlayer_SetCamera();
-float CSQCPlayer_PreUpdate();
-float CSQCPlayer_PostUpdate();
-float CSQCPlayer_IsLocalPlayer();
+float CSQCPlayer_PreUpdate(entity this);
+float CSQCPlayer_PostUpdate(entity this);
+float CSQCPlayer_IsLocalPlayer(entity this);
#endif
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\
IN THE SOFTWARE.\
-";
+"; // "
.vector glowmod;
.vector view_ofs;
*/
#include "interpolate.qh"
-#if defined(CSQC)
-// #include "../../client/defs.qh"
-// #include "../warpzone/anglestransform.qh"
-// #include "../../client/autocvars.qh"
-// #include "cl_model.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
-#endif
-
+// 1 = old, 2 = new
.vector iorigin1, iorigin2;
.vector ivelocity1, ivelocity2;
.vector iforward1, iforward2;
.vector ivup1, ivup2;
.float itime1, itime2;
void InterpolateOrigin_Reset()
-{SELFPARAM();
+{
+ SELFPARAM();
self.iflags &= ~IFLAG_INTERNALMASK;
self.itime1 = self.itime2 = 0;
}
-void InterpolateOrigin_Note()
-{SELFPARAM();
- float dt;
- int f0;
-
- dt = time - self.itime2;
+void InterpolateOrigin_Note(entity this)
+{
+ float dt = time - this.itime2;
- f0 = self.iflags;
- if(self.iflags & IFLAG_PREVALID)
- self.iflags |= IFLAG_VALID;
- else
- self.iflags |= IFLAG_PREVALID;
+ int f0 = this.iflags;
+ if (this.iflags & IFLAG_PREVALID) this.iflags |= IFLAG_VALID;
+ else this.iflags |= IFLAG_PREVALID;
- if(self.iflags & IFLAG_ORIGIN)
+ if (this.iflags & IFLAG_ORIGIN)
{
- self.iorigin1 = self.iorigin2;
- self.iorigin2 = self.origin;
+ this.iorigin1 = this.iorigin2;
+ this.iorigin2 = this.origin;
}
- if(self.iflags & IFLAG_AUTOANGLES)
- if(self.iorigin2 != self.iorigin1)
- self.angles = vectoangles(self.iorigin2 - self.iorigin1);
+ if (this.iflags & IFLAG_AUTOANGLES
+ && this.iorigin2
+ != this.iorigin1) this.angles = vectoangles(this.iorigin2 - this.iorigin1);
- if(self.iflags & IFLAG_AUTOVELOCITY)
- if(self.itime2 != self.itime1)
- self.velocity = (self.iorigin2 - self.iorigin1) * (1.0 / (self.itime2 - self.itime1));
+ if (this.iflags & IFLAG_AUTOVELOCITY
+ && this.itime2
+ != this.itime1) this.velocity = (this.iorigin2 - this.iorigin1) * (1.0 / (this.itime2 - this.itime1));
- if(self.iflags & IFLAG_ANGLES)
+ if (this.iflags & IFLAG_ANGLES)
{
- fixedmakevectors(self.angles);
- if(f0 & IFLAG_VALID)
+ fixedmakevectors(this.angles);
+ if (f0 & IFLAG_VALID)
{
- self.iforward1 = self.iforward2;
- self.iup1 = self.iup2;
+ this.iforward1 = this.iforward2;
+ this.iup1 = this.iup2;
}
else
{
- self.iforward1 = v_forward;
- self.iup1 = v_up;
+ this.iforward1 = v_forward;
+ this.iup1 = v_up;
}
- self.iforward2 = v_forward;
- self.iup2 = v_up;
+ this.iforward2 = v_forward;
+ this.iup2 = v_up;
}
- if(self.iflags & IFLAG_V_ANGLE)
+ if (this.iflags & IFLAG_V_ANGLE)
{
- fixedmakevectors(self.v_angle);
- if(f0 & IFLAG_VALID)
+ fixedmakevectors(this.v_angle);
+ if (f0 & IFLAG_VALID)
{
- self.ivforward1 = self.ivforward2;
- self.ivup1 = self.ivup2;
+ this.ivforward1 = this.ivforward2;
+ this.ivup1 = this.ivup2;
}
else
{
- self.ivforward1 = v_forward;
- self.ivup1 = v_up;
+ this.ivforward1 = v_forward;
+ this.ivup1 = v_up;
}
- self.ivforward2 = v_forward;
- self.ivup2 = v_up;
+ this.ivforward2 = v_forward;
+ this.ivup2 = v_up;
}
- else if(self.iflags & IFLAG_V_ANGLE_X)
+ else if (this.iflags & IFLAG_V_ANGLE_X)
{
- self.ivforward1_x = self.ivforward2_x;
- self.ivforward2_x = self.v_angle.x;
+ this.ivforward1_x = this.ivforward2_x;
+ this.ivforward2_x = this.v_angle.x;
}
- if(self.iflags & IFLAG_VELOCITY)
+ if (this.iflags & IFLAG_VELOCITY)
{
- self.ivelocity1 = self.ivelocity2;
- self.ivelocity2 = self.velocity;
+ this.ivelocity1 = this.ivelocity2;
+ this.ivelocity2 = this.velocity;
}
- if(self.iflags & IFLAG_TELEPORTED)
+ if (this.iflags & IFLAG_TELEPORTED)
{
- self.iflags &= ~IFLAG_TELEPORTED;
- self.itime1 = self.itime2 = time; // don't lerp
+ this.iflags &= ~IFLAG_TELEPORTED;
+ this.itime1 = this.itime2 = time; // don't lerp
}
- else if(vlen(self.iorigin2 - self.iorigin1) > 1000)
+ else if (vdist(this.iorigin2 - this.iorigin1, >, 1000))
{
- self.itime1 = self.itime2 = time; // don't lerp
+ this.itime1 = this.itime2 = time; // don't lerp
}
- else if((self.iflags & IFLAG_VELOCITY) && (vlen(self.ivelocity2 - self.ivelocity1) > 1000))
+ else if ((this.iflags & IFLAG_VELOCITY) && vdist(this.ivelocity2 - this.ivelocity1, >, 1000))
{
- self.itime1 = self.itime2 = time; // don't lerp
+ this.itime1 = this.itime2 = time; // don't lerp
}
- else if(dt >= 0.2)
+ else if (dt >= 0.2)
{
- self.itime1 = self.itime2 = time;
+ this.itime1 = this.itime2 = time;
}
else
{
- self.itime1 = serverprevtime;
- self.itime2 = time;
+ this.itime1 = serverprevtime;
+ this.itime2 = time;
}
}
-void InterpolateOrigin_Do()
-{SELFPARAM();
- vector forward, up;
- if(self.itime1 && self.itime2 && self.itime1 != self.itime2)
+
+/** set origin based on iorigin1 (old pos), iorigin2 (desired pos), and time */
+void InterpolateOrigin_Do(entity this)
+{
+ if (this.itime1 && this.itime2 && this.itime1 != this.itime2)
{
- float f;
- f = bound(0, (time - self.itime1) / (self.itime2 - self.itime1), 1 + autocvar_cl_lerpexcess);
- if(self.iflags & IFLAG_ORIGIN)
- setorigin(self, (1 - f) * self.iorigin1 + f * self.iorigin2);
- if(self.iflags & IFLAG_ANGLES)
+ float f = bound(0, (time - this.itime1) / (this.itime2 - this.itime1), 1 + autocvar_cl_lerpexcess);
+ float f_1 = 1 - f;
+ if (this.iflags & IFLAG_ORIGIN) setorigin(this, f_1 * this.iorigin1 + f * this.iorigin2);
+ if (this.iflags & IFLAG_ANGLES)
{
- forward = (1 - f) * self.iforward1 + f * self.iforward2;
- up = (1 - f) * self.iup1 + f * self.iup2;
- self.angles = fixedvectoangles2(forward, up);
+ vector forward = f_1 * this.iforward1 + f * this.iforward2;
+ vector up = f_1 * this.iup1 + f * this.iup2;
+ this.angles = fixedvectoangles2(forward, up);
}
- if(self.iflags & IFLAG_V_ANGLE)
+ if (this.iflags & IFLAG_V_ANGLE)
{
- forward = (1 - f) * self.ivforward1 + f * self.ivforward2;
- up = (1 - f) * self.ivup1 + f * self.ivup2;
- self.v_angle = fixedvectoangles2(forward, up);
+ vector forward = f_1 * this.ivforward1 + f * this.ivforward2;
+ vector up = f_1 * this.ivup1 + f * this.ivup2;
+ this.v_angle = fixedvectoangles2(forward, up);
}
- else if(self.iflags & IFLAG_V_ANGLE_X)
- self.v_angle_x = (1 - f) * self.ivforward1_x + f * self.ivforward2_x;
- if(self.iflags & IFLAG_VELOCITY)
- self.velocity = (1 - f) * self.ivelocity1 + f * self.ivelocity2;
+ else if (this.iflags & IFLAG_V_ANGLE_X)
+ {
+ this.v_angle_x = f_1 * this.ivforward1.x + f * this.ivforward2.x;
+ }
+ if (this.iflags & IFLAG_VELOCITY) this.velocity = f_1 * this.ivelocity1 + f * this.ivelocity2;
}
}
-void InterpolateOrigin_Undo()
-{SELFPARAM();
- if(self.iflags & IFLAG_ORIGIN)
- setorigin(self, self.iorigin2);
- if(self.iflags & IFLAG_ANGLES)
- self.angles = fixedvectoangles2(self.iforward2, self.iup2);
- if(self.iflags & IFLAG_V_ANGLE)
- self.v_angle = fixedvectoangles2(self.ivforward2, self.ivup2);
- else if(self.iflags & IFLAG_V_ANGLE_X)
- self.v_angle_x = self.ivforward2_x;
- if(self.iflags & IFLAG_VELOCITY)
- self.velocity = self.ivelocity2;
-}
+/** snap origin to iorigin2 (actual origin) */
+void InterpolateOrigin_Undo(entity this)
+{
+ if (this.iflags & IFLAG_ORIGIN) setorigin(this, this.iorigin2);
+ if (this.iflags & IFLAG_ANGLES) this.angles = fixedvectoangles2(this.iforward2, this.iup2);
+ if (this.iflags & IFLAG_V_ANGLE) this.v_angle = fixedvectoangles2(this.ivforward2, this.ivup2);
+ else if (this.iflags & IFLAG_V_ANGLE_X) this.v_angle_x = this.ivforward2_x;
+ if (this.iflags & IFLAG_VELOCITY) this.velocity = this.ivelocity2;
+}
const int IFLAG_INTERNALMASK = IFLAG_VALID | IFLAG_PREVALID;
// call this BEFORE reading an entity update
-void InterpolateOrigin_Undo();
+void InterpolateOrigin_Undo(entity this);
// call this AFTER receiving an entity update
-void InterpolateOrigin_Note();
+void InterpolateOrigin_Note(entity this);
// call this when the entity got teleported, before InterpolateOrigin_Note
void InterpolateOrigin_Reset();
// call this BEFORE drawing
-void InterpolateOrigin_Do();
+void InterpolateOrigin_Do(entity this);
// in case we interpolate that:
.vector v_angle;
class(Defer).void() think;
class(Defer).float nextthink;
-/*
-==================
-SUB_Remove
+ /** Remove self */
+ void SUB_Remove(entity this)
+ {
+ remove(this);
+ }
-Remove self
-==================
-*/
- void SUB_Remove()
+ /** Remove self */
+ void SUB_Remove_self()
{
SELFPARAM();
- remove(self);
+ remove(this);
}
void defer_think()
{
SELFPARAM();
- self.think = SUB_Remove;
- self.nextthink = time;
- WITH(entity, self, self.owner, self.use());
+ this.think = SUB_Remove_self;
+ this.nextthink = time;
+ WITH(entity, self, this.owner, this.use());
}
/*
Execute func() after time + fdelay.
self when func is executed = self when defer is called
*/
- void defer(float fdelay, void() func)
+ void defer(entity this, float fdelay, void() func)
{
- SELFPARAM();
-
entity e = new(deferred);
make_pure(e);
e.owner = this;
do \
{ \
for (int i = start; i < end; ++i) \
- { \
- const noref entity it = arr[i]; \
- if (cond) { body } \
- } \
+ { \
+ const noref entity it = arr[i]; \
+ if (cond) { body } \
+ } \
} \
while (0)
#define FOREACH_LIST(list, next, cond, body) \
do \
- { \
- noref int i = 0; \
+ { \
+ int i = 0; \
for (entity it = list##_first; it; (it = it.next, ++i)) \
- { \
- if (cond) { body } \
- } \
+ { \
+ if (cond) { body } \
+ } \
+ } \
+ while (0)
+
+#define FOREACH_WORD(words, cond, body) \
+ do \
+ { \
+ string _words = words; \
+ int i = 0; \
+ for (string _it; (_it = car(_words)); (_words = cdr(_words), ++i)) \
+ { \
+ const noref string it = _it; \
+ if (cond) { body } \
+ } \
+ } \
+ while (0)
+
+#if defined(CSQC)
+ entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #403;
+#elif defined(SVQC)
+ entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #403;
+#elif defined(MENUQC)
+ entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #27;
+#endif
+
+.entity _FOREACH_ENTITY_fld;
+.entity _FOREACH_ENTITY_next;
+
+#define FOREACH_ENTITY_UNORDERED(cond, body) \
+ do { \
+ int i = 0; \
+ for (entity it = findchainentity_tofield(_FOREACH_ENTITY_fld, NULL, _FOREACH_ENTITY_next); it; (it = it._FOREACH_ENTITY_next, ++i)) \
+ { \
+ if (cond) { body } \
+ } \
} \
while (0)
+#define FOREACH_ENTITY_ORDERED(cond, body) \
+ do { \
+ int i = 0; \
+ for (entity it = NULL; (it = nextent(it)); ++i) \
+ { \
+ if (cond) { body } \
+ } \
+ } \
+ while (0)
+
+#define FOREACH_ENTITY(cond, body) FOREACH_ENTITY_UNORDERED(cond, body)
+
#define FOREACH(list, cond, body) FOREACH_LIST(list, enemy, cond, body)
#endif
#define LL_NEW() NEW(LinkedList)
+#define LL_EMPTY(ll) (ll.ll_head == NULL)
+
/**
* Push to tail
*/
#define MAP_H
// Databases (hash tables)
-const float DB_BUCKETS = 8192;
-void db_save(float db, string pFilename)
+const int DB_BUCKETS = 8192;
+void db_save(int db, string filename)
{
- int fh = fopen(pFilename, FILE_WRITE);
+ int fh = fopen(filename, FILE_WRITE);
if (fh < 0)
{
- LOG_INFO(strcat("^1Can't write DB to ", pFilename));
+ LOG_WARNINGF("^1Can't write DB to %s\n", filename);
return;
}
- int n = buf_getsize(db);
fputs(fh, strcat(ftos(DB_BUCKETS), "\n"));
- for (int i = 0; i < n; ++i)
+ for (int i = 0, n = buf_getsize(db); i < n; ++i)
fputs(fh, strcat(bufstr_get(db, i), "\n"));
fclose(fh);
}
return buf_create();
}
-void db_put(float db, string pKey, string pValue);
+void db_put(int db, string key, string value);
-int db_load(string pFilename)
+int db_load(string filename)
{
int db = buf_create();
if (db < 0) return -1;
- int fh = fopen(pFilename, FILE_READ);
+ int fh = fopen(filename, FILE_READ);
if (fh < 0) return db;
string l = fgets(fh);
- if (stof(l) == DB_BUCKETS)
+ if (stoi(l) == DB_BUCKETS)
{
for (int i = 0; (l = fgets(fh)); ++i)
{
return db;
}
-void db_dump(float db, string pFilename)
+void db_dump(int db, string filename)
{
- int fh = fopen(pFilename, FILE_WRITE);
- if (fh < 0) error(strcat("Can't dump DB to ", pFilename));
- int n = buf_getsize(db);
+ int fh = fopen(filename, FILE_WRITE);
+ if (fh < 0) LOG_FATALF("Can't dump DB to %s\n");
fputs(fh, "0\n");
- for (int i = 0; i < n; ++i)
+ for (int i = 0, n = buf_getsize(db); i < n; ++i)
{
int m = tokenizebyseparator(bufstr_get(db, i), "\\");
for (int j = 2; j < m; j += 2)
fclose(fh);
}
-void db_close(float db)
+void db_close(int db)
{
buf_del(db);
}
-string db_get(float db, string pKey)
+string db_get(int db, string key)
{
- int h = crc16(false, pKey) % DB_BUCKETS;
- return uri_unescape(infoget(bufstr_get(db, h), pKey));
+ int h = crc16(false, key) % DB_BUCKETS;
+ return uri_unescape(infoget(bufstr_get(db, h), key));
}
-void db_put(float db, string pKey, string pValue)
+#define db_remove(db, key) db_put(db, key, "")
+
+void db_put(int db, string key, string value)
{
- int h = crc16(false, pKey) % DB_BUCKETS;
- bufstr_set(db, h, infoadd(bufstr_get(db, h), pKey, uri_escape(pValue)));
+ int h = crc16(false, key) % DB_BUCKETS;
+ bufstr_set(db, h, infoadd(bufstr_get(db, h), key, uri_escape(value)));
}
void db_test()
.int Version; // deprecated, use SendFlags
.int SendFlags;
.bool(entity to, int sendflags) SendEntity;
+ /** return false to remove from the client */
.bool(entity this, entity to, int sendflags) SendEntity3;
bool SendEntity_self(entity to, int sendflags) { return self.SendEntity3(self, to, sendflags); }
if (dt)
{
e.nextthink = time + dt;
- e.think = SUB_Remove;
+ e.think = SUB_Remove_self;
}
}
#ifdef CSQC
#define REGISTER_NET_LINKED(id) \
- [[accumulate]] NET_HANDLE(id, bool) \
+ [[accumulate]] NET_HANDLE(id, bool isnew) \
{ \
this = self; \
this.sourceLocFile = __FILE__; \
this.sourceLocLine = __LINE__; \
+ if (!this) isnew = true; \
} \
- REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, new(net_linked_packet)) \
+ REGISTER(LinkedEntities, NET, id, m_id, new(net_linked_packet)) \
{ \
make_pure(this); \
this.netname = #id; \
#else
#define REGISTER_NET_LINKED(id) \
const bool NET_##id##_istemp = false; \
- REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, new(net_linked_packet)) \
+ REGISTER(LinkedEntities, NET, id, m_id, new(net_linked_packet)) \
{ \
make_pure(this); \
this.netname = #id; \
REGISTRY(LinkedEntities, BITS(8) - 1)
#define LinkedEntities_from(i) _LinkedEntities_from(i, NULL)
-REGISTER_REGISTRY(RegisterLinkedEntities)
-REGISTRY_SORT(LinkedEntities, 0)
+REGISTER_REGISTRY(LinkedEntities)
+REGISTRY_SORT(LinkedEntities)
REGISTRY_CHECK(LinkedEntities)
STATIC_INIT(RegisterLinkedEntities_renumber)
{
#ifdef CSQC
#define REGISTER_NET_TEMP(id) \
NET_HANDLE(id, bool); \
- REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, new(net_temp_packet)) \
+ REGISTER(TempEntities, NET, id, m_id, new(net_temp_packet)) \
{ \
make_pure(this); \
this.netname = #id; \
#else
#define REGISTER_NET_TEMP(id) \
const bool NET_##id##_istemp = true; \
- REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, new(net_temp_packet)) \
+ REGISTER(TempEntities, NET, id, m_id, new(net_temp_packet)) \
{ \
make_pure(this); \
this.netname = #id; \
REGISTRY(TempEntities, BITS(8) - 80)
#define TempEntities_from(i) _TempEntities_from(i, NULL)
-REGISTER_REGISTRY(RegisterTempEntities)
-REGISTRY_SORT(TempEntities, 0)
+REGISTER_REGISTRY(TempEntities)
+REGISTRY_SORT(TempEntities)
REGISTRY_CHECK(TempEntities)
STATIC_INIT(RegisterTempEntities_renumber)
{
return v;
}
+ #define ReadFloat() ReadCoord()
+ vector ReadVector() { vector v; v.x = ReadFloat(); v_y = ReadFloat(); v.z = ReadFloat(); return v; }
+ vector ReadVector2D() { vector v; v.x = ReadFloat(); v.y = ReadFloat(); v.z = 0; return v; }
+
float ReadApproxPastTime()
{
float dt = ReadByte();
WriteInt24_t(dst, val.z);
}
+ #define WriteFloat(to, f) WriteCoord(to, f)
+ #define WriteVector(to, v) do { WriteFloat(to, v.x); WriteFloat(to, v.y); WriteFloat(to, v.z); } while (0)
+ #define WriteVector2D(to, v) do { WriteFloat(to, v.x); WriteFloat(to, v.y); } while (0)
+
// this will use the value:
// 128
// accuracy near zero is APPROXPASTTIME_MAX/(256*255)
#include "oo.qh"
-#define REGISTER_REGISTRY(func) ACCUMULATE_FUNCTION(__static_init, func)
-
-#define REGISTER_INIT(ns, id) [[accumulate]] void Register_##ns##_##id##_init(entity this)
-#define REGISTER_INIT_POST(ns, id) [[accumulate]] void Register_##ns##_##id##_init_post(entity this)
+#if 1
+ #define _R_MAP(r, max) AL_declare(r); STATIC_INIT(r) { AL_init(r, max, NULL, e); }
+ #define _R_GET(r, i) AL_gete(r, i)
+ #define _R_SET(r, i, e) AL_sete(r, i, e)
+#else
+ #define _R_MAP(r, max) entity r[max]
+ #define _R_GET(r, i) r[i]
+ #define _R_SET(r, i, e) r[i] = e
+#endif
+/**
+ * Declare a new registry.
+ *
+ * Don't forget to call `REGISTER_REGISTRY`:
+ * REGISTER_REGISTRY(Foos)
+ */
#define REGISTRY(id, max) \
void Register##id() {} \
const int id##_MAX = max; \
- noref entity _##id[id##_MAX], id##_first, id##_last; \
+ noref entity id##_first, id##_last; \
+ _R_MAP(_##id, id##_MAX); \
int id##_COUNT; \
- entity _##id##_from(int i, entity null) { if (i >= 0 && i < id##_COUNT) { entity e = _##id[i]; if (e) return e; } return null; }
+ entity _##id##_from(int i, entity null) { if (i >= 0 && i < id##_COUNT) { entity e = _R_GET(_##id, i); if (e) return e; } return null; }
+
+REGISTRY(Registries, BITS(8))
/** registered item identifier */
.string registered_id;
/**
- * Register a new entity with a global constructor.
+ * Register a new entity with a registry.
* Must be followed by a semicolon or a function body with a `this` parameter.
* Wrapper macros may perform actions after user initialization like so:
* #define REGISTER_FOO(id) \
- * REGISTER(RegisterFoos, FOO, FOOS, id, m_id, NEW(Foo)); \
+ * REGISTER(Foos, FOO, id, m_id, NEW(Foo)); \
* REGISTER_INIT_POST(FOO, id) { \
* print("Registering foo #", this.m_id + 1, "\n"); \
* } \
* REGISTER_INIT(FOO, id)
*
- * Don't forget to forward declare `initfunc` and call `REGISTER_REGISTRY`:
- * void RegisterFoos();
- * REGISTER_REGISTRY(RegisterFoos)
*
- * @param initfunc The global constructor to accumulate into
+ * @param registry The registry to add each entity to.
* @param ns Short for namespace, prefix for each global (ns##_##id)
- * @param array The array to add each entity to. Also requires `array##_first` and `array##_last` to be defined
* @param id The identifier of the current entity being registered
- * @param fld The field to store the current count into
+ * @param fld The field to store the locally unique unique entity id
* @param inst An expression to create a new instance, invoked for every registration
*/
-#define REGISTER(initfunc, ns, array, id, fld, inst) \
- entity ns##_##id; \
- REGISTER_INIT(ns, id) {} \
- REGISTER_INIT_POST(ns, id) {} \
- void Register_##ns##_##id() \
+#define REGISTER(...) EVAL(OVERLOAD(REGISTER, __VA_ARGS__))
+#define REGISTER_5(registry, ns, id, fld, inst) REGISTER_4(registry, ns##_##id, fld, inst)
+#define REGISTER_4(registry, id, fld, inst) \
+ entity id; \
+ REGISTER_INIT(id) {} \
+ REGISTER_INIT_POST(id) {} \
+ void Register_##id() \
{ \
- if (array##_COUNT >= array##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(array##_MAX)); \
- entity this = inst; \
- ns##_##id = this; \
+ if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(registry##_MAX)); \
+ entity this = id = inst; \
this.registered_id = #id; \
- REGISTRY_PUSH(array, fld, this); \
- Register_##ns##_##id##_init(this); \
- Register_##ns##_##id##_init_post(this); \
+ REGISTRY_PUSH(registry, fld, this); \
+ Register_##id##_init(this); \
+ Register_##id##_init_post(this); \
} \
- ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id) \
- REGISTER_INIT(ns, id)
-
-#define REGISTRY_PUSH(array, fld, it) do { \
- it.fld = array##_COUNT; \
- _##array[array##_COUNT++] = it; \
- if (!array##_first) array##_first = it; \
- if (array##_last) array##_last.REGISTRY_NEXT = it; \
- array##_last = it; \
+ ACCUMULATE_FUNCTION(Register##registry, Register_##id) \
+ REGISTER_INIT(id)
+
+#define REGISTRY_PUSH(registry, fld, it) do { \
+ it.fld = registry##_COUNT; \
+ _R_SET(_##registry, registry##_COUNT, it); \
+ ++registry##_COUNT; \
+ if (!registry##_first) registry##_first = it; \
+ if (registry##_last) registry##_last.REGISTRY_NEXT = it; \
+ registry##_last = it; \
} while (0)
#define REGISTRY_RESERVE(registry, fld, id, suffix) do { \
entity e = new(registry_reserved); \
- e.registered_id = #id #suffix; \
+ e.registered_id = #id "/" #suffix; \
REGISTRY_PUSH(registry, fld, e); \
} while (0)
+#define REGISTER_INIT(id) [[accumulate]] void Register_##id##_init(entity this)
+#define REGISTER_INIT_POST(id) [[accumulate]] void Register_##id##_init_post(entity this)
+
/** internal next pointer */
#define REGISTRY_NEXT enemy
.entity REGISTRY_NEXT;
-#define REGISTRY_SORT(id, skip) \
+#define REGISTRY_SORT(...) EVAL(OVERLOAD(REGISTRY_SORT, __VA_ARGS__))
+#define REGISTRY_SORT_1(id) REGISTRY_SORT_2(id, 0)
+#define REGISTRY_SORT_2(id, skip) \
void _REGISTRY_SWAP_##id(int i, int j, entity pass) \
{ \
i += skip; j += skip; \
\
- entity a = _##id[i], b = _##id[j]; \
- _##id[i] = b; \
- _##id[j] = a; \
+ entity a = _R_GET(_##id, i), b = _R_GET(_##id, j); \
+ _R_SET(_##id, i, b); \
+ _R_SET(_##id, j, a); \
\
entity a_next = a.REGISTRY_NEXT, b_next = b.REGISTRY_NEXT; \
a.REGISTRY_NEXT = b_next; \
b.REGISTRY_NEXT = a_next; \
\
if (i == 0) id##_first = b; \
- else _##id[i - 1].REGISTRY_NEXT = b; \
+ else _R_GET(_##id, i - 1).REGISTRY_NEXT = b; \
\
if (j == 0) id##_first = a; \
- else _##id[j - 1].REGISTRY_NEXT = a; \
+ else _R_GET(_##id, j - 1).REGISTRY_NEXT = a; \
} \
int _REGISTRY_CMP_##id(int i, int j, entity pass) \
{ \
i += skip; j += skip; \
- string a = _##id[i].registered_id; \
- string b = _##id[j].registered_id; \
+ string a = _R_GET(_##id, i).registered_id; \
+ string b = _R_GET(_##id, j).registered_id; \
return strcmp(a, b); \
} \
STATIC_INIT(Registry_sort_##id) \
string h = REGISTRY_HASH(id) = strzone(digest_hex(algo, s)); \
LOG_TRACEF(#id ": %s\n[%s]\n", h, s); \
} \
- [[accumulate]] void Registry_check(string r, string sv) \
+ void Registry_check(string r, string sv) \
{ \
if (r == #id) \
{ \
} \
} \
} \
- [[accumulate]] void Registry_send_all() { Registry_send(#id, REGISTRY_HASH(id)); } \
+ void Registry_send_all() { Registry_send(#id, REGISTRY_HASH(id)); } \
+
+#define REGISTER_REGISTRY(...) EVAL(OVERLOAD(REGISTER_REGISTRY, __VA_ARGS__))
+#define REGISTER_REGISTRY_1(id) REGISTER_REGISTRY_2(id, #id)
+#define REGISTER_REGISTRY_2(id, str) \
+ ACCUMULATE_FUNCTION(__static_init, Register##id) \
+ CLASS(id##Registry, Object) \
+ ATTRIB(id##Registry, m_name, string, str) \
+ ATTRIB(id##Registry, REGISTRY_NEXT, entity, id##_first) \
+ ENDCLASS(id##Registry) \
+ REGISTER(Registries, REGISTRY, id, m_id, NEW(id##Registry));
+
#endif
#define _spawnfunc_check(fld) \
if (fieldname == #fld) continue;
- #define spawnfunc_1(id, whitelist) spawnfunc_2(id, whitelist)
+ bool __spawnfunc_unreachable_workaround = true;
+
+ #define spawnfunc_1(id) spawnfunc_2(id, FIELDS_UNION)
#define spawnfunc_2(id, whitelist) \
- void spawnfunc_##id(entity this) \
+ void __spawnfunc_##id(entity this); \
+ [[accumulate]] void spawnfunc_##id(entity this) \
{ \
this = self; \
if (!this.sourceLocFile) \
} \
this.spawnfunc_checked = true; \
} \
+ __spawnfunc_##id(this); \
+ if (__spawnfunc_unreachable_workaround) return; \
} \
- [[accumulate]] void spawnfunc_##id(entity this)
+ void __spawnfunc_##id(entity this)
#define FIELD_SCALAR(fld, n) \
fld(n)
FIELD_VEC(fld, velocity) \
/**/
- #define spawnfunc(...) EVAL(OVERLOAD(spawnfunc, __VA_ARGS__, FIELDS_UNION))
+ #define spawnfunc(...) EVAL(OVERLOAD(spawnfunc, __VA_ARGS__))
#endif
#define _STAT(id) g_stat_##id
#define REGISTER_STAT_2(id, T) \
T _STAT(id); \
- REGISTER(RegisterStats, STAT, Stats, id, m_id, new(stat)) \
+ REGISTER(Stats, STAT_##id, m_id, new(stat)) \
{ \
make_pure(this); \
if (#T == "vector" || #T == "vectori") { \
- REGISTRY_RESERVE(Stats, m_id, id, _y); \
- REGISTRY_RESERVE(Stats, m_id, id, _z); \
+ REGISTRY_RESERVE(Stats, m_id, STAT_##id, y); \
+ REGISTRY_RESERVE(Stats, m_id, STAT_##id, z); \
} \
} \
[[accumulate]] void stats_get() \
#define _STAT(id) stat_##id
#define REGISTER_STAT_2(id, T) \
.T _STAT(id); \
- REGISTER(RegisterStats, STAT, Stats, id, m_id, new(stat)) \
+ REGISTER(Stats, STAT_##id, m_id, new(stat)) \
{ \
make_pure(this); \
if (#T == "vector" || #T == "vectori") { \
- REGISTRY_RESERVE(Stats, m_id, id, _y); \
- REGISTRY_RESERVE(Stats, m_id, id, _z); \
+ REGISTRY_RESERVE(Stats, m_id, STAT_##id, y); \
+ REGISTRY_RESERVE(Stats, m_id, STAT_##id, z); \
} \
} \
[[accumulate]] void stats_add() \
const int STATS_ENGINE_RESERVE = 32;
REGISTRY(Stats, 256 - STATS_ENGINE_RESERVE)
-REGISTER_REGISTRY(RegisterStats)
-REGISTRY_SORT(Stats, 0)
+REGISTER_REGISTRY(Stats)
+REGISTRY_SORT(Stats)
REGISTRY_CHECK(Stats)
STATIC_INIT(RegisterStats_renumber)
{
#ifndef VECTOR_H
#define VECTOR_H
+noref vector _vlen2;
+#define vlen2(v) \
+ (_vlen2 = (v), \
+ _vlen2.x * _vlen2.x \
+ + _vlen2.y * _vlen2.y \
+ + _vlen2.z * _vlen2.z)
+
+noref float _vdist_f;
+/** Vector distance comparison, avoids sqrt() */
+#define vdist(v, cmp, f) (vlen2(v) cmp (_vdist_f = (f), _vdist_f * _vdist_f))
+/*
+#define vdist(v, cmp, f) (vlen(v) cmp (f))
+*/
+
+#define cross(a, b) ((a) >< (b))
+/*
+vector cross(vector a, vector b)
+{
+ return
+ '1 0 0' * (a.y * b.z - a.z * b.y)
+ + '0 1 0' * (a.z * b.x - a.x * b.z)
+ + '0 0 1' * (a.x * b.y - a.y * b.x);
+}
+*/
+
const vector eX = '1 0 0';
const vector eY = '0 1 0';
const vector eZ = '0 0 1';
return v;
}
-float vlen2d(vector v)
-{
- return sqrt(v.x * v.x + v.y * v.y);
-}
-
float vlen_maxnorm2d(vector v)
{
return max(v.x, v.y, -v.x, -v.y);
float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) { return smins.x >= bmins.x && smaxs.x <= bmaxs.x && smins.y >= bmins.y && smaxs.y <= bmaxs.y && smins.z >= bmins.z && smaxs.z <= bmaxs.z; }
-vector vec2(vector v)
-{
- v.z = 0;
- return v;
-}
+noref vector _vec2;
+#define vec2(v) (_vec2 = (v), _vec2.z = 0, _vec2)
-vector vec3(float x, float y, float z)
-{
- vector v;
- v.x = x;
- v.y = y;
- v.z = z;
- return v;
-}
+noref vector _vec3;
+#define vec3(x, y, z) (_vec3_x = (x), _vec3_y = (y), _vec3_z = (z), _vec3)
vector rotate(vector v, float a)
{
return r;
}
-vector yinvert(vector v)
-{
- v.y = 1 - v.y;
- return v;
-}
+noref vector _yinvert;
+#define yinvert(v) (_yinvert = (v), _yinvert.y = 1 - _yinvert.y, _yinvert)
#ifndef MENUQC
vector get_corner_position(entity box, int corner)
#include "anglestransform.qh"
-#ifdef POSITIVE_PITCH_IS_DOWN
-vector fixedvectoangles(vector a)
-{
- vector ang;
- ang = vectoangles(a);
- ang.x = -ang.x;
- return ang;
-}
-vector fixedvectoangles2(vector a, vector b)
-{
- vector ang;
- ang = vectoangles2(a, b);
- ang.x = -ang.x;
- return ang;
-}
-#else
-void fixedmakevectors(vector a)
-{
- // a makevectors that actually inverts vectoangles
- a.x = -a.x;
- makevectors(a);
-}
-#endif
-
// angles transforms
// angles in fixedmakevectors/fixedvectoangles space
vector AnglesTransform_Apply(vector transform, vector v)
return t;
}
-#ifdef POSITIVE_PITCH_IS_DOWN
+#if POSITIVE_PITCH_IS_DOWN
vector AnglesTransform_ApplyToAngles(vector transform, vector v)
{
v.x = -v.x;
#ifndef LIB_WARPZONE_ANGLETRANSFORM_H
#define LIB_WARPZONE_ANGLETRANSFORM_H
-#define POSITIVE_PITCH_IS_DOWN
+#ifndef POSITIVE_PITCH_IS_DOWN
+#define POSITIVE_PITCH_IS_DOWN 1
+#endif
-#ifdef POSITIVE_PITCH_IS_DOWN
-#define fixedmakevectors makevectors
-vector fixedvectoangles(vector a);
-vector fixedvectoangles2(vector a, vector b);
+#if POSITIVE_PITCH_IS_DOWN
+ #define fixedmakevectors makevectors
+ noref vector _fixedvectoangles;
+ #define fixedvectoangles(a) (_fixedvectoangles = vectoangles(a), _fixedvectoangles.x *= -1, _fixedvectoangles)
+ noref vector _fixedvectoangles2;
+ #define fixedvectoangles2(a, b) (_fixedvectoangles2 = vectoangles2(a, b), _fixedvectoangles2.x *= -1, _fixedvectoangles2)
#else
-void fixedmakevectors(vector a);
-#define fixedvectoangles2 vectoangles2
-#define fixedvectoangles vectoangles
+ void fixedmakevectors(vector a)
+ {
+ // a makevectors that actually inverts vectoangles
+ a.x = -a.x;
+ makevectors(a);
+ }
+ #define fixedvectoangles2 vectoangles2
+ #define fixedvectoangles vectoangles
#endif
vector AnglesTransform_Apply(vector transform, vector v);
if (is_pure(e)) return true;
switch (s)
{
- case "entcs_sender":
- case "entcs_receiver":
// case "net_linked": // actually some real entities are linked without classname, fail
case "":
return true;
{
return !(x < y || x == y || x > y);
}
-
-vector cross(vector a, vector b)
-{
- return
- '1 0 0' * (a.y * b.z - a.z * b.y)
- + '0 1 0' * (a.z * b.x - a.x * b.z)
- + '0 0 1' * (a.x * b.y - a.y * b.x);
-}
const float M_SQRT2 = 1.41421356237309504880; /* sqrt(2) */
const float M_SQRT1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
-// Non-<math.h> stuff follows here.
-vector cross(vector a, vector b);
-
#endif
ts.SendEntity = WarpZone_Teleported_Send;
ts.SendFlags = 0xFFFFFF;
ts.drawonlytoclient = player;
- ts.think = SUB_Remove;
+ ts.think = SUB_Remove_self;
ts.nextthink = time + 1;
ts.owner = player;
ts.enemy = wz;
}
void WarpZone_StartFrame()
-{SELFPARAM();
- entity e;
- if(warpzone_initialized == 0)
+{
+ SELFPARAM();
+ if (!warpzone_initialized)
{
- warpzone_initialized = 1;
- for(setself(warpzone_first); self; setself(self.warpzone_next))
+ warpzone_initialized = true;
+ for (setself(warpzone_first); self; setself(self.warpzone_next))
WarpZone_InitStep_FindOriginTarget();
- for(setself(warpzone_position_first); self; setself(self.warpzone_next))
+ for (setself(warpzone_position_first); self; setself(self.warpzone_next))
WarpZonePosition_InitStep_FindTarget();
- for(setself(warpzone_first); self; setself(self.warpzone_next))
+ for (setself(warpzone_first); self; setself(self.warpzone_next))
WarpZone_InitStep_UpdateTransform();
setself(this);
WarpZones_Reconnect();
WarpZone_PostInitialize_Callback();
}
- entity oldother;
- oldother = other;
- for(e = world; (e = nextent(e)); )
+ entity oldother = other;
+ for (entity e = world; (e = nextent(e)); )
{
- if(warpzone_warpzones_exist) { WarpZone_StoreProjectileData(e); }
-
- if(IS_REAL_CLIENT(e))
+ if (warpzone_warpzones_exist) WarpZone_StoreProjectileData(e);
+ if (IS_REAL_CLIENT(e))
{
- if(e.solid == SOLID_NOT) // not spectating?
- if(e.movetype == MOVETYPE_NOCLIP || e.movetype == MOVETYPE_FLY || e.movetype == MOVETYPE_FLY_WORLDONLY) // not spectating? (this is to catch observers)
+ if (e.solid == SOLID_NOT) // not spectating?
+ if (e.movetype == MOVETYPE_NOCLIP || e.movetype == MOVETYPE_FLY || e.movetype == MOVETYPE_FLY_WORLDONLY) // not spectating? (this is to catch observers)
{
other = e; // player
// warpzones
- if(warpzone_warpzones_exist) {
- setself(WarpZone_Find(e.origin + e.mins, e.origin + e.maxs));
- if(self)
- if(!WarpZoneLib_ExactTrigger_Touch())
- if(WarpZone_PlaneDist(self, e.origin + e.view_ofs) <= 0)
- WarpZone_Teleport(self, e, -1, 0); } // NOT triggering targets by this!
+ if (warpzone_warpzones_exist) {
+ setself(WarpZone_Find(e.origin + e.mins, e.origin + e.maxs));
+ if (self)
+ if (!WarpZoneLib_ExactTrigger_Touch())
+ if (WarpZone_PlaneDist(self, e.origin + e.view_ofs) <= 0)
+ WarpZone_Teleport(self, e, -1, 0); // NOT triggering targets by this!
+ }
// teleporters
setself(Teleport_Find(e.origin + e.mins, e.origin + e.maxs));
- if(self)
- if(!WarpZoneLib_ExactTrigger_Touch())
+ if (self)
+ if (!WarpZoneLib_ExactTrigger_Touch())
Simple_TeleportPlayer(self, other); // NOT triggering targets by this!
}
}
-
- if(IS_NOT_A_CLIENT(e))
+ else if (IS_NOT_A_CLIENT(e))
{
- if(warpzone_warpzones_exist)
- for (; (e = nextent(e)); )
+ if (warpzone_warpzones_exist)
+ while ((e = nextent(e)))
WarpZone_StoreProjectileData(e);
break;
}
}
.float warpzone_reconnecting;
-float visible_to_some_client(entity ent)
+bool visible_to_some_client(entity ent)
{
- entity e;
- for(e = nextent(world); !IS_NOT_A_CLIENT(e); e = nextent(e))
- if(IS_PLAYER(e) && IS_REAL_CLIENT(e))
- if(checkpvs(e.origin + e.view_ofs, ent))
- return 1;
- return 0;
+ FOREACH_ENTITY(!IS_NOT_A_CLIENT(it), LAMBDA(
+ if (IS_PLAYER(it) && IS_REAL_CLIENT(it) && checkpvs(it.origin + it.view_ofs, ent)) return true;
+ ));
+ return false;
}
void trigger_warpzone_reconnect_use()
{SELFPARAM();
if (argc == 1)
{
LOG_INFO(_("Available options:\n"));
- float i;
- entity e;
- string s;
- for (i = 0, e = NULL; (e = nextent(e)); )
- if (e.classname != "vtbl" && e.name != "")
+ FOREACH_ENTITY_ORDERED(it.name != "", LAMBDA(
+ if (it.classname == "vtbl") continue;
+ string s = it.name;
+ if (filter)
{
- s = e.name;
- if (filter)
- {
- if (substring(s, 0, strlen(filter)) != filter) continue;
- s = substring(s, strlen(filter), strlen(s) - strlen(filter));
- }
- LOG_INFO(strcat(" ", s, "\n"));
- ++i;
+ if (!startsWith(s, filter)) continue;
+ s = substring(s, strlen(filter), strlen(s) - strlen(filter));
}
+ LOG_INFOF(" %s\n", s);
+ ));
}
else if (argc == 2 && !isdemo()) // don't allow this command in demos
{
REGISTRY(Settings, BITS(3))
#define Settings_from(i) _Settings_from(i, NULL)
-REGISTER_REGISTRY(RegisterSettings)
+REGISTER_REGISTRY(Settings)
#define REGISTER_SETTINGS(id, impl) \
LAZY_NEW(id, impl) \
- REGISTER(RegisterSettings, MENU, Settings, id, m_id, NEW(Lazy, LAZY(id)))
+ REGISTER(Settings, MENU, id, m_id, NEW(Lazy, LAZY(id)))
#endif
#endif
#define ITEM_H
#include "skin.qh"
CLASS(Item, Object)
- METHOD(Item, draw, void(entity));
- METHOD(Item, keyDown, float(entity, float, float, float));
- METHOD(Item, keyUp, float(entity, float, float, float));
- METHOD(Item, mouseMove, float(entity, vector));
- METHOD(Item, mousePress, float(entity, vector));
- METHOD(Item, mouseDrag, float(entity, vector));
- METHOD(Item, mouseRelease, float(entity, vector));
- METHOD(Item, focusEnter, void(entity));
- METHOD(Item, focusLeave, void(entity));
- METHOD(Item, resizeNotify, void(entity, vector, vector, vector, vector));
- METHOD(Item, relinquishFocus, void(entity));
- METHOD(Item, showNotify, void(entity));
- METHOD(Item, hideNotify, void(entity));
- METHOD(Item, toString, string(entity));
- METHOD(Item, destroy, void(entity));
+ METHOD(Item, draw, void(Item));
+ METHOD(Item, keyDown, float(Item, float, float, float));
+ METHOD(Item, keyUp, float(Item, float, float, float));
+ METHOD(Item, mouseMove, float(Item, vector));
+ METHOD(Item, mousePress, float(Item, vector));
+ METHOD(Item, mouseDrag, float(Item, vector));
+ METHOD(Item, mouseRelease, float(Item, vector));
+ METHOD(Item, focusEnter, void(Item));
+ METHOD(Item, focusLeave, void(Item));
+ METHOD(Item, resizeNotify, void(Item, vector, vector, vector, vector));
+ METHOD(Item, relinquishFocus, void(Item));
+ METHOD(Item, showNotify, void(Item));
+ METHOD(Item, hideNotify, void(Item));
+ METHOD(Item, toString, string(Item));
+ METHOD(Item, destroy, void(Item));
ATTRIB(Item, focused, float, 0)
ATTRIB(Item, focusable, float, 0)
ATTRIB(Item, allowFocusSound, float, 0)
#endif
#ifdef IMPLEMENTATION
-void Item_destroy(entity me)
-{
- // free memory associated with me
-}
-
-void Item_relinquishFocus(entity me)
-{
- if(me.parent)
- if(me.parent.instanceOfContainer)
- me.parent.setFocus(me.parent, NULL);
-}
-
-void Item_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
-{
- me.origin = absOrigin;
- me.size = absSize;
-}
-
-float autocvar_menu_showboxes;
-void Item_draw(entity me)
-{
- if(autocvar_menu_showboxes)
+ METHOD(Item, destroy, void(Item this))
{
+ // free memory associated with this
+ }
+
+ METHOD(Item, relinquishFocus, void(Item this))
+ {
+ entity par = this.parent;
+ if (!par) return;
+ if (par.instanceOfContainer) par.setFocus(par, NULL);
+ }
+
+ METHOD(Item, resizeNotify, void(Item this, vector relOrigin, vector relSize, vector absOrigin, vector absSize))
+ {
+ this.origin = absOrigin;
+ this.size = absSize;
+ }
+
+ int autocvar_menu_showboxes;
+ METHOD(Item, draw, void(Item this))
+ {
+ if (!autocvar_menu_showboxes) return;
vector rgb = '1 0 1';
float a = fabs(autocvar_menu_showboxes);
// don't draw containers and border images
- if(me.instanceOfContainer || me.instanceOfBorderImage)
+ if (this.instanceOfContainer || this.instanceOfBorderImage)
{
rgb = '0 0 0';
a = 0;
}
-#if 0
- // hack to detect multi drawing
- float r = random() * 3;
- if(r >= 2)
- rgb = '1 0 0';
- else if(r >= 1)
- rgb = '0 1 0';
- else
- rgb = '0 0 1';
-#endif
- if(autocvar_menu_showboxes < 0)
+ #if 0
+ // hack to detect multi drawing
+ float r = random() * 3;
+ if (r >= 2) rgb = '1 0 0';
+ else if (r >= 1) rgb = '0 1 0';
+ else rgb = '0 0 1';
+ #endif
+ if (autocvar_menu_showboxes < 0)
{
draw_Fill('0 0 0', '0.5 0.5 0', rgb, a);
draw_Fill('0.5 0.5 0', '0.5 0.5 0', rgb, a);
}
- if(autocvar_menu_showboxes > 0)
+ else if (autocvar_menu_showboxes > 0)
{
draw_Fill('0 0 0', '1 1 0', rgb, a);
}
}
-}
-
-void Item_showNotify(entity me)
-{
-}
-
-void Item_hideNotify(entity me)
-{
-}
-
-float Item_keyDown(entity me, float scan, float ascii, float shift)
-{
- return 0; // unhandled
-}
-
-float Item_keyUp(entity me, float scan, float ascii, float shift)
-{
- return 0; // unhandled
-}
-
-float Item_mouseMove(entity me, vector pos)
-{
- return 0; // unhandled
-}
-
-float Item_mousePress(entity me, vector pos)
-{
- return 0; // unhandled
-}
-
-float Item_mouseDrag(entity me, vector pos)
-{
- return 0; // unhandled
-}
-
-float Item_mouseRelease(entity me, vector pos)
-{
- return 0; // unhandled
-}
-
-void Item_focusEnter(entity me)
-{
- if(me.allowFocusSound)
- m_play_focus_sound();
-}
-
-void Item_focusLeave(entity me)
-{
-}
-
-string Item_toString(entity me)
-{
- return string_null;
-}
+
+ METHOD(Item, showNotify, void(Item this))
+ {}
+
+ METHOD(Item, hideNotify, void(Item this))
+ {}
+
+ METHOD(Item, keyDown, float(Item this, float scan, float ascii, float shift))
+ {
+ return 0; // unhandled
+ }
+
+ METHOD(Item, keyUp, float(Item this, float scan, float ascii, float shift))
+ {
+ return 0; // unhandled
+ }
+
+ METHOD(Item, mouseMove, float(Item this, vector pos))
+ {
+ return 0; // unhandled
+ }
+
+ METHOD(Item, mousePress, float(Item this, vector pos))
+ {
+ return 0; // unhandled
+ }
+
+ METHOD(Item, mouseDrag, float(Item this, vector pos))
+ {
+ return 0; // unhandled
+ }
+
+ METHOD(Item, mouseRelease, float(Item this, vector pos))
+ {
+ return 0; // unhandled
+ }
+
+ METHOD(Item, focusEnter, void(Item this))
+ {
+ if (this.allowFocusSound) m_play_focus_sound();
+ }
+
+ METHOD(Item, focusLeave, void(Item this))
+ {}
+
+ METHOD(Item, toString, string(Item this))
+ {
+ return string_null;
+ }
#endif
save = draw_alpha;
if (me.disabled) draw_alpha *= me.disabledAlpha;
draw_ButtonPicture('0 0 0', strcat(me.src, "_s"), eX * (1 - me.textSpace) + eY, me.color2, 1);
+ if (me.valueMax > me.valueMin) // valid?
if (almost_in_bounds(me.valueMin, me.sliderValue, me.valueMax))
{
controlLeft = (me.sliderValue - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth);
me.sliderAnim = NULL;
}
- me.setText(me, me.valueToText(me, me.value));
+ if (me.valueMax > me.valueMin) // valid?
+ me.setText(me, me.valueToText(me, me.value));
draw_alpha = save;
SUPER(Slider).draw(me);
me.text = string_null; // TEMPSTRING!
#include "../common/mapinfo.qh"
#include "../common/mutators/base.qh"
-///////////////////////////////////////////////
-// Menu Source File
-///////////////////////
-// This file belongs to dpmod/darkplaces
-// AK contains all menu functions (especially the required ones)
-///////////////////////////////////////////////
-
-float mouseButtonsPressed;
+int mouseButtonsPressed;
vector menuMousePos;
int menuShiftState;
float menuPrevTime;
float menuAlpha;
float menuLogoAlpha;
float prevMenuAlpha;
-float menuInitialized;
-float menuNotTheFirstFrame;
-float menuMouseMode;
+bool menuInitialized;
+bool menuNotTheFirstFrame;
+int menuMouseMode;
-float conwidth_s, conheight_s, vidwidth_s, vidheight_s, vidpixelheight_s,
- realconwidth, realconheight;
+float conwidth_s, conheight_s;
+float vidwidth_s, vidheight_s, vidpixelheight_s;
+float realconwidth, realconheight;
void m_sync()
{
updateCompression();
- vidwidth_s = vidheight_s = vidpixelheight_s = 0; // Force updateConwidths on next draw.
+ vidwidth_s = vidheight_s = vidpixelheight_s = 0; // Force updateConwidths on next draw
loadAllCvars(main);
}
void m_gamestatus()
{
gamestatus = 0;
- if(isserver())
- gamestatus = gamestatus | GAME_ISSERVER;
- if(clientstate() == CS_CONNECTED || isdemo())
- gamestatus = gamestatus | GAME_CONNECTED;
- if(cvar("developer"))
- gamestatus = gamestatus | GAME_DEVELOPER;
+ if (isserver()) gamestatus |= GAME_ISSERVER;
+ if (clientstate() == CS_CONNECTED || isdemo()) gamestatus |= GAME_CONNECTED;
+ if (cvar("developer")) gamestatus |= GAME_DEVELOPER;
}
void m_init()
{
- float restarting = 0;
+ bool restarting = false;
cvar_set("_menu_alpha", "0");
prvm_language = cvar_string("prvm_language");
- if(prvm_language == "")
+ if (prvm_language == "")
{
prvm_language = "en";
cvar_set("prvm_language", prvm_language);
localcmd("\nmenu_restart\n");
- restarting = 1;
+ restarting = true;
}
prvm_language = strzone(prvm_language);
cvar_set("_menu_prvm_language", prvm_language);
#ifdef WATERMARK
- LOG_TRACEF("^4MQC Build information: ^1%s\n", WATERMARK);
+ LOG_INFOF("^4MQC Build information: ^1%s\n", WATERMARK);
#endif
// list all game dirs (TEST)
- if(cvar("developer"))
+ if (cvar("developer"))
{
- float i;
- string s;
- for(i = 0; ; ++i)
+ for (int i = 0; ; ++i)
{
- s = getgamedirinfo(i, GETGAMEDIRINFO_NAME);
- if (!s)
- break;
+ string s = getgamedirinfo(i, GETGAMEDIRINFO_NAME);
+ if (!s) break;
LOG_TRACE(s, ": ", getgamedirinfo(i, GETGAMEDIRINFO_DESCRIPTION));
}
}
float ddsload = cvar("r_texture_dds_load");
float texcomp = cvar("gl_texturecompression");
updateCompression();
- if(ddsload != cvar("r_texture_dds_load") || texcomp != cvar("gl_texturecompression"))
- localcmd("\nr_restart\n");
+ if (ddsload != cvar("r_texture_dds_load") || texcomp != cvar("gl_texturecompression")) localcmd("\nr_restart\n");
- if(!restarting)
+ if (!restarting)
{
- if(cvar("_menu_initialized")) // always show menu after menu_restart
+ if (cvar("_menu_initialized")) // always show menu after menu_restart
m_display();
- else
- m_hide();
+ else m_hide();
cvar_set("_menu_initialized", "1");
}
-
}
-const float MENU_ASPECT = 1.25; // 1280x1024
+const float MENU_ASPECT = 1280 / 1024;
void draw_reset_cropped()
{
{
if (w != vidwidth_s || h != vidheight_s || p != vidpixelheight_s)
{
- if (updateConwidths(w, h, p))
- localcmd(sprintf("\nexec %s\n", cvar_string("menu_font_cfg")));
+ if (updateConwidths(w, h, p)) localcmd(sprintf("\nexec %s\n", cvar_string("menu_font_cfg")));
vidwidth_s = w;
vidheight_s = h;
vidpixelheight_s = p;
conheight_s = conheight;
realconwidth = cvar("vid_conwidth");
realconheight = cvar("vid_conheight");
- if(realconwidth / realconheight > MENU_ASPECT)
+ if (realconwidth / realconheight > MENU_ASPECT)
{
// widescreen
conwidth = realconheight * MENU_ASPECT;
conwidth = realconwidth;
conheight = realconwidth / MENU_ASPECT;
}
- if(main)
+ if (main)
{
- if(conwidth_s != conwidth || conheight_s != conheight)
+ if (conwidth_s != conwidth || conheight_s != conheight)
{
draw_reset_cropped();
main.resizeNotify(main, '0 0 0', eX * conwidth + eY * conheight, '0 0 0', eX * conwidth + eY * conheight);
}
else
{
- vidwidth_s = vidheight_s = vidpixelheight_s = 0; // retry next frame
+ vidwidth_s = vidheight_s = vidpixelheight_s = 0; // retry next frame
}
}
string m_goto_buffer;
void m_init_delayed()
{
- float fh, glob, n, i;
- string s;
-
draw_reset_cropped();
- menuInitialized = 0;
- if(!preMenuInit())
- return;
- menuInitialized = 1;
+ menuInitialized = false;
+ if (!preMenuInit()) return;
+ menuInitialized = true;
- fh = -1;
- if(cvar_string("menu_skin") != "")
+ int fh = -1;
+ if (cvar_string("menu_skin") != "")
{
draw_currentSkin = strcat("gfx/menu/", cvar_string("menu_skin"));
fh = fopen(language_filename(strcat(draw_currentSkin, "/skinvalues.txt")), FILE_READ);
}
- if(fh < 0)
- if(cvar_defstring("menu_skin") != "")
+ if (fh < 0 && cvar_defstring("menu_skin") != "")
{
cvar_set("menu_skin", cvar_defstring("menu_skin"));
draw_currentSkin = strcat("gfx/menu/", cvar_string("menu_skin"));
fh = fopen(language_filename(strcat(draw_currentSkin, "/skinvalues.txt")), FILE_READ);
}
- if(fh < 0)
+ if (fh < 0)
{
draw_currentSkin = "gfx/menu/default";
fh = fopen(language_filename(strcat(draw_currentSkin, "/skinvalues.txt")), FILE_READ);
}
- if(fh < 0)
- {
- error("cannot load any menu skin\n");
- }
+ if (fh < 0) error("cannot load any menu skin\n");
draw_currentSkin = strzone(draw_currentSkin);
- while((s = fgets(fh)))
+ for (string s; (s = fgets(fh)); )
{
// these two are handled by skinlist.qc
- if(substring(s, 0, 6) == "title ")
- continue;
- if(substring(s, 0, 7) == "author ")
- continue;
- n = tokenize_console(s);
- if(n >= 2)
- Skin_ApplySetting(argv(0), substring(s, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)));
+ if (substring(s, 0, 6) == "title ") continue;
+ if (substring(s, 0, 7) == "author ") continue;
+ int n = tokenize_console(s);
+ if (n < 2) continue;
+ Skin_ApplySetting(argv(0), substring(s, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)));
}
fclose(fh);
- glob = search_begin(strcat(draw_currentSkin, "/*.tga"), true, true);
- if(glob >= 0)
+ int glob = search_begin(strcat(draw_currentSkin, "/*.tga"), true, true);
+ if (glob >= 0)
{
- n = search_getsize(glob);
- for(i = 0; i < n; ++i)
+ for (int i = 0, n = search_getsize(glob); i < n; ++i)
precache_pic(search_getfilename(glob, i));
search_end(glob);
}
draw_setMousePointer(SKINGFX_CURSOR, SKINSIZE_CURSOR, SKINOFFSET_CURSOR);
anim = NEW(AnimHost);
- main = NEW(MainWindow); main.configureMainWindow(main);
+ main = NEW(MainWindow);
+ main.configureMainWindow(main);
main.resizeNotify(main, '0 0 0', eX * conwidth + eY * conheight, '0 0 0', eX * conwidth + eY * conheight);
- main.focused = 1;
+ main.focused = true;
menuShiftState = 0;
menuMousePos = '0.5 0.5 0';
m_sync();
- if(m_goto_buffer)
+ if (m_goto_buffer)
{
m_goto(m_goto_buffer);
strunzone(m_goto_buffer);
m_goto_buffer = string_null;
}
- if(Menu_Active)
- m_display(); // delayed menu display
+ if (Menu_Active) m_display(); // delayed menu display
}
-void m_keyup (float key, float ascii)
+void m_keyup(float key, float ascii)
{
- if(!menuInitialized)
- return;
- if(!Menu_Active)
- return;
+ if (!menuInitialized) return;
+ if (!Menu_Active) return;
draw_reset_cropped();
main.keyUp(main, key, ascii, menuShiftState);
- if(key >= K_MOUSE1 && key <= K_MOUSE3)
+ if (key >= K_MOUSE1 && key <= K_MOUSE3)
{
--mouseButtonsPressed;
- if(!mouseButtonsPressed)
- main.mouseRelease(main, menuMousePos);
- if(mouseButtonsPressed < 0)
+ if (!mouseButtonsPressed) main.mouseRelease(main, menuMousePos);
+ if (mouseButtonsPressed < 0)
{
mouseButtonsPressed = 0;
LOG_TRACE("Warning: released an already released button\n");
}
}
- if(key == K_ALT) menuShiftState -= (menuShiftState & S_ALT);
- if(key == K_CTRL) menuShiftState -= (menuShiftState & S_CTRL);
- if(key == K_SHIFT) menuShiftState -= (menuShiftState & S_SHIFT);
+ if (key == K_ALT) menuShiftState &= ~S_ALT;
+ if (key == K_CTRL) menuShiftState &= ~S_CTRL;
+ if (key == K_SHIFT) menuShiftState &= ~S_SHIFT;
}
void m_keydown(float key, float ascii)
{
- if(!menuInitialized)
- return;
- if(!Menu_Active)
- return;
+ if (!menuInitialized) return;
+ if (!Menu_Active) return;
- if(menuMouseMode)
- if(key >= K_MOUSE1 && key <= K_MOUSE3)
+ if (menuMouseMode && key >= K_MOUSE1 && key <= K_MOUSE3)
{
// detect a click outside of the game window
vector p = getmousepos();
- if(p.x < 0 || p.x > realconwidth || p.y < 0 || p.y > realconheight)
+ if (p.x < 0 || p.x > realconwidth || p.y < 0 || p.y > realconheight)
{
++mouseButtonsPressed;
return;
}
}
- if(keyGrabber)
+ if (keyGrabber)
{
- entity e;
- e = keyGrabber;
+ entity e = keyGrabber;
keyGrabber = NULL;
e.keyGrabbed(e, key, ascii);
}
else
{
draw_reset_cropped();
- if(key >= K_MOUSE1 && key <= K_MOUSE3)
- if(!mouseButtonsPressed)
- main.mousePress(main, menuMousePos);
- if(!main.keyDown(main, key, ascii, menuShiftState))
- if(key == K_ESCAPE)
- if(gamestatus & (GAME_ISSERVER | GAME_CONNECTED)) // don't back out to console only
- m_hide(); // disable menu on unhandled ESC
+ if (!mouseButtonsPressed && key >= K_MOUSE1 && key <= K_MOUSE3) main.mousePress(main, menuMousePos);
+ if (!main.keyDown(main, key, ascii, menuShiftState))
+ {
+ // disable menu on unhandled ESC
+ if (key == K_ESCAPE)
+ if (gamestatus & (GAME_ISSERVER | GAME_CONNECTED)) // don't back out to console only
+ m_hide();
+ }
}
- if(key >= K_MOUSE1 && key <= K_MOUSE3)
+ if (key >= K_MOUSE1 && key <= K_MOUSE3)
{
++mouseButtonsPressed;
- if(mouseButtonsPressed > 10)
+ if (mouseButtonsPressed > 10)
{
mouseButtonsPressed = 10;
LOG_TRACE("Warning: pressed an already pressed button\n");
}
}
- if(key == K_ALT) menuShiftState |= S_ALT;
- if(key == K_CTRL) menuShiftState |= S_CTRL;
- if(key == K_SHIFT) menuShiftState |= S_SHIFT;
+ if (key == K_ALT) menuShiftState |= S_ALT;
+ if (key == K_CTRL) menuShiftState |= S_CTRL;
+ if (key == K_SHIFT) menuShiftState |= S_SHIFT;
}
-const float SCALEMODE_CROP = 0;
-const float SCALEMODE_LETTERBOX = 1;
-const float SCALEMODE_WIDTH = 2;
-const float SCALEMODE_HEIGHT = 3;
-const float SCALEMODE_STRETCH = 4;
+enum {
+ SCALEMODE_CROP,
+ SCALEMODE_LETTERBOX,
+ SCALEMODE_WIDTH,
+ SCALEMODE_HEIGHT,
+ SCALEMODE_STRETCH,
+};
void draw_Picture_Aligned(vector algn, float scalemode, string img, float a)
{
- vector sz, org, isz, isz_w, isz_h;
- float width_is_larger;
-
- sz = draw_PictureSize(img);
- width_is_larger = (sz.x * draw_scale.y >= sz.y * draw_scale.x);
- isz_w = '1 0 0' + '0 1 0' * ((sz.y / sz.x) * (draw_scale.x / draw_scale.y));
- isz_h = '0 1 0' + '1 0 0' * ((sz.x / sz.y) * (draw_scale.y / draw_scale.x));
-
- switch(scalemode)
+ vector sz = draw_PictureSize(img);
+ bool width_is_larger = (sz.x * draw_scale.y >= sz.y * draw_scale.x);
+ vector isz_w = '1 0 0' + '0 1 0' * ((sz.y / sz.x) * (draw_scale.x / draw_scale.y));
+ vector isz_h = '0 1 0' + '1 0 0' * ((sz.x / sz.y) * (draw_scale.y / draw_scale.x));
+ vector isz;
+ switch (scalemode)
{
default:
case SCALEMODE_CROP:
isz = '1 1 0';
break;
}
-
- org = eX * (algn.x * (1 - isz.x)) + eY * (algn.y * (1 - isz.y));
+ vector org = eX * (algn.x * (1 - isz.x)) + eY * (algn.y * (1 - isz.y));
draw_Picture(org, img, isz, '1 1 1', a);
}
void drawBackground(string img, float a, string algn, float force1)
{
- if(main.mainNexposee.ModalController_state == 0)
- return;
-
- vector v;
- float i, l;
- string c;
- float scalemode;
-
- v.z = 0;
-
- scalemode = SCALEMODE_CROP;
-
- l = 0;
- for(i = 0; i < strlen(algn); ++i)
+ if (main.mainNexposee.ModalController_state == 0) return;
+ vector v = '0 0 0';
+ int scalemode = SCALEMODE_CROP;
+ for (int i = 0, l = 0; i < strlen(algn); ++i)
{
- c = substring(algn, i, 1);
- switch(c)
+ string c = substring(algn, i, 1);
+ switch (c)
{
- case "c": scalemode = SCALEMODE_CROP; goto nopic;
- case "l": scalemode = SCALEMODE_LETTERBOX; goto nopic;
- case "h": scalemode = SCALEMODE_HEIGHT; goto nopic;
- case "w": scalemode = SCALEMODE_WIDTH; goto nopic;
- case "s": scalemode = SCALEMODE_STRETCH; goto nopic;
- case "1": case "4": case "7": v.x = 0.0; break;
- case "2": case "5": case "8": v.x = 0.5; break;
- case "3": case "6": case "9": v.x = 1.0; break;
- default: v.x = random(); break;
+ case "c":
+ scalemode = SCALEMODE_CROP;
+ goto nopic;
+ case "l":
+ scalemode = SCALEMODE_LETTERBOX;
+ goto nopic;
+ case "h":
+ scalemode = SCALEMODE_HEIGHT;
+ goto nopic;
+ case "w":
+ scalemode = SCALEMODE_WIDTH;
+ goto nopic;
+ case "s":
+ scalemode = SCALEMODE_STRETCH;
+ goto nopic;
+ case "1": case "4": case "7":
+ v.x = 0.0;
+ break;
+ case "2": case "5": case "8":
+ v.x = 0.5;
+ break;
+ case "3": case "6": case "9":
+ v.x = 1.0;
+ break;
+ default:
+ v.x = random();
+ break;
}
- switch(c)
+ switch (c)
{
- case "7": case "8": case "9": v.y = 0.0; break;
- case "4": case "5": case "6": v.y = 0.5; break;
- case "1": case "2": case "3": v.y = 1.0; break;
- default: v.y = random(); break;
+ case "7": case "8": case "9":
+ v.y = 0.0;
+ break;
+ case "4": case "5": case "6":
+ v.y = 0.5;
+ break;
+ case "1": case "2": case "3":
+ v.y = 1.0;
+ break;
+ default:
+ v.y = random();
+ break;
}
- if(l == 0)
+ if (l == 0)
+ {
draw_Picture_Aligned(v, scalemode, img, a);
- else if(force1)
+ }
+ else if (force1)
+ {
// force all secondary layers to use alpha 1. Prevents ugly issues
// with overlap. It's a flag because it cannot be used for the
// ingame background
- draw_Picture_Aligned(v, scalemode, strcat(img, "_l", ftos(l+1)), 1);
+ draw_Picture_Aligned(v, scalemode, strcat(img, "_l", ftos(l + 1)), 1);
+ }
else
- draw_Picture_Aligned(v, scalemode, strcat(img, "_l", ftos(l+1)), a);
+ {
+ draw_Picture_Aligned(v, scalemode, strcat(img, "_l", ftos(l + 1)), a);
+ }
++l;
-:nopic
+ : nopic
}
}
-float menu_tooltips;
-float menu_tooltips_old;
+int menu_tooltips;
+int menu_tooltips_old;
vector menuTooltipAveragedMousePos;
entity menuTooltipItem;
vector menuTooltipOrigin;
vector menuTooltipSize;
float menuTooltipAlpha;
string menuTooltipText;
-float menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
-float m_testmousetooltipbox(vector pos)
+int menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
+bool m_testmousetooltipbox(vector pos)
{
- if(pos.x >= menuTooltipOrigin.x && pos.x < menuTooltipOrigin.x + menuTooltipSize.x)
- if(pos.y >= menuTooltipOrigin.y && pos.y < menuTooltipOrigin.y + menuTooltipSize.y)
- return false;
- return true;
+ return !(
+ (pos.x >= menuTooltipOrigin.x && pos.x < menuTooltipOrigin.x + menuTooltipSize.x)
+ && (pos.y >= menuTooltipOrigin.y && pos.y < menuTooltipOrigin.y + menuTooltipSize.y)
+ );
}
-float m_testtooltipbox(vector tooltippos)
+bool m_testtooltipbox(vector tooltippos)
{
- if(tooltippos.x < 0)
- return false;
- if(tooltippos.y < 0)
- return false;
- if(tooltippos.x + menuTooltipSize.x > 1)
- return false;
- if(tooltippos.y + menuTooltipSize.y > 1)
- return false;
+ if (tooltippos.x < 0) return false;
+ if (tooltippos.y < 0) return false;
+ if (tooltippos.x + menuTooltipSize.x > 1) return false;
+ if (tooltippos.y + menuTooltipSize.y > 1) return false;
menuTooltipOrigin = tooltippos;
return true;
}
-float m_allocatetooltipbox(vector pos)
+bool m_allocatetooltipbox(vector pos)
{
- vector avoidplus, avoidminus;
- vector v;
-
+ vector avoidplus;
avoidplus.x = (SKINAVOID_TOOLTIP_x + SKINSIZE_CURSOR_x - SKINOFFSET_CURSOR_x * SKINSIZE_CURSOR_x) / conwidth;
avoidplus.y = (SKINAVOID_TOOLTIP_y + SKINSIZE_CURSOR_y - SKINOFFSET_CURSOR_y * SKINSIZE_CURSOR_y) / conheight;
avoidplus.z = 0;
+ vector avoidminus;
avoidminus.x = (SKINAVOID_TOOLTIP_x + SKINOFFSET_CURSOR_x * SKINSIZE_CURSOR_x) / conwidth + menuTooltipSize.x;
avoidminus.y = (SKINAVOID_TOOLTIP_y + SKINOFFSET_CURSOR_y * SKINSIZE_CURSOR_y) / conheight + menuTooltipSize.y;
avoidminus.z = 0;
// bottom right
- v = pos + avoidplus;
- if(m_testtooltipbox(v))
- return true;
+ vector v = pos + avoidplus;
+ if (m_testtooltipbox(v)) return true;
// bottom center
v.x = pos.x - menuTooltipSize.x * 0.5;
- if(m_testtooltipbox(v))
- return true;
+ if (m_testtooltipbox(v)) return true;
// bottom left
v.x = pos.x - avoidminus.x;
- if(m_testtooltipbox(v))
- return true;
+ if (m_testtooltipbox(v)) return true;
// top left
v.y = pos.y - avoidminus.y;
- if(m_testtooltipbox(v))
- return true;
+ if (m_testtooltipbox(v)) return true;
// top center
v.x = pos.x - menuTooltipSize.x * 0.5;
- if(m_testtooltipbox(v))
- return true;
+ if (m_testtooltipbox(v)) return true;
// top right
v.x = pos.x + avoidplus.x;
- if(m_testtooltipbox(v))
- return true;
+ if (m_testtooltipbox(v)) return true;
return false;
}
entity m_findtooltipitem(entity root, vector pos)
{
- entity it;
- entity best;
-
- best = NULL;
- it = root;
-
- while(it.instanceOfContainer)
+ entity best = NULL;
+ for (entity it = root; it.instanceOfContainer; )
{
- while(it.instanceOfNexposee && it.focusedChild)
+ while (it.instanceOfNexposee && it.focusedChild)
{
it = it.focusedChild;
pos = globalToBox(pos, it.Container_origin, it.Container_size);
}
- if(it.instanceOfNexposee)
+ if (it.instanceOfNexposee)
{
it = it.itemFromPoint(it, pos);
- if(it.tooltip)
- best = it;
- else if(menu_tooltips == 2 && (it.cvarName || it.onClickCommand))
- best = it;
+ if (it.tooltip) best = it;
+ else if (menu_tooltips == 2 && (it.cvarName || it.onClickCommand)) best = it;
it = NULL;
}
- else if(it.instanceOfModalController)
+ else if (it.instanceOfModalController)
+ {
it = it.focusedChild;
+ }
else
+ {
it = it.itemFromPoint(it, pos);
- if(!it)
- break;
- if(it.tooltip)
- best = it;
- else if(menu_tooltips == 2 && (it.cvarName || it.onClickCommand))
- best = it;
+ }
+ if (!it) break;
+ if (it.tooltip) best = it;
+ else if (menu_tooltips == 2 && (it.cvarName || it.onClickCommand)) best = it;
pos = globalToBox(pos, it.Container_origin, it.Container_size);
}
string s;
if (menuTooltipItem.cvarName)
{
- if (getCvarsMulti(menuTooltipItem))
- s = strcat("[", menuTooltipItem.cvarName, " ", getCvarsMulti(menuTooltipItem), "]");
- else
- s = strcat("[", menuTooltipItem.cvarName, "]");
+ if (getCvarsMulti(menuTooltipItem)) s =
+ strcat("[", menuTooltipItem.cvarName, " ", getCvarsMulti(menuTooltipItem), "]");
+ else s = strcat("[", menuTooltipItem.cvarName, "]");
}
else if (menuTooltipItem.onClickCommand)
+ {
s = strcat("<", menuTooltipItem.onClickCommand, ">");
+ }
else
+ {
return menuTooltipItem.tooltip;
- if (menuTooltipItem.tooltip)
- return strcat(menuTooltipItem.tooltip, " ", s);
+ }
+ if (menuTooltipItem.tooltip) return strcat(menuTooltipItem.tooltip, " ", s);
return s;
}
return menuTooltipItem.tooltip;
}
-string prev_tooltip;
void m_tooltip(vector pos)
{
- float f, i, w;
+ static string prev_tooltip;
entity it;
- vector fontsize, p;
- string s;
-
menu_tooltips = cvar("menu_tooltips");
if (!menu_tooltips)
{
// don't return immediately, fade out the active tooltip first
- if (menuTooltipItem == NULL)
- return;
+ if (menuTooltipItem == NULL) return;
it = NULL;
menu_tooltips_old = menu_tooltips;
}
else
{
- f = bound(0, frametime * 2, 1);
+ float f = bound(0, frametime * 2, 1);
menuTooltipAveragedMousePos = menuTooltipAveragedMousePos * (1 - f) + pos * f;
f = vlen(pos - menuTooltipAveragedMousePos);
- if(f < 0.01)
+ if (f < 0.01)
{
it = m_findtooltipitem(main, pos);
- if(it.instanceOfListBox && it.isScrolling(it))
- it = world;
+ if (it.instanceOfListBox && it.isScrolling(it)) it = world;
- if(it && prev_tooltip != it.tooltip)
+ if (it && prev_tooltip != it.tooltip)
{
// fade out if tooltip of a certain item has changed
menuTooltipState = 3;
- if(prev_tooltip)
- strunzone(prev_tooltip);
+ if (prev_tooltip) strunzone(prev_tooltip);
prev_tooltip = strzone(it.tooltip);
}
- else if(menuTooltipItem && !m_testmousetooltipbox(pos))
- menuTooltipState = 3; // fade out if mouse touches it
-
+ else if (menuTooltipItem && !m_testmousetooltipbox(pos))
+ {
+ menuTooltipState = 3; // fade out if mouse touches it
+ }
}
else
+ {
it = NULL;
+ }
}
- fontsize = '1 0 0' * (SKINFONTSIZE_TOOLTIP / conwidth) + '0 1 0' * (SKINFONTSIZE_TOOLTIP / conheight);
+ vector fontsize = '1 0 0' * (SKINFONTSIZE_TOOLTIP / conwidth) + '0 1 0' * (SKINFONTSIZE_TOOLTIP / conheight);
// float menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
- if(it != menuTooltipItem)
+ if (it != menuTooltipItem)
{
- switch(menuTooltipState)
+ switch (menuTooltipState)
{
case 0:
- if(menuTooltipItem)
+ if (menuTooltipItem)
{
// another item: fade out first
menuTooltipState = 2;
menuTooltipState = 1;
menuTooltipItem = it;
- menuTooltipOrigin.x = -1; // unallocated
+ menuTooltipOrigin.x = -1; // unallocated
- if (menuTooltipText)
- strunzone(menuTooltipText);
+ if (menuTooltipText) strunzone(menuTooltipText);
menuTooltipText = strzone(gettooltip());
- i = 0;
- w = 0;
- getWrappedLine_remaining = menuTooltipText;
- while(getWrappedLine_remaining)
+ int i = 0;
+ float w = 0;
+ for (getWrappedLine_remaining = menuTooltipText; getWrappedLine_remaining; ++i)
{
- s = getWrappedLine(SKINWIDTH_TOOLTIP, fontsize, draw_TextWidth_WithoutColors);
- ++i;
- f = draw_TextWidth(s, false, fontsize);
- if(f > w)
- w = f;
+ string s = getWrappedLine(SKINWIDTH_TOOLTIP, fontsize, draw_TextWidth_WithoutColors);
+ float f = draw_TextWidth(s, false, fontsize);
+ if (f > w) w = f;
}
menuTooltipSize.x = w + 2 * (SKINMARGIN_TOOLTIP_x / conwidth);
menuTooltipSize.y = i * fontsize.y + 2 * (SKINMARGIN_TOOLTIP_y / conheight);
break;
}
}
- else if(menuTooltipState == 2) // re-fade in?
+ else if (menuTooltipState == 2) // re-fade in?
+ {
menuTooltipState = 1;
+ }
- switch(menuTooltipState)
+ switch (menuTooltipState)
{
- case 1: // fade in
+ case 1: // fade in
menuTooltipAlpha = bound(0, menuTooltipAlpha + 5 * frametime, 1);
- if(menuTooltipAlpha == 1)
- menuTooltipState = 0;
+ if (menuTooltipAlpha == 1) menuTooltipState = 0;
break;
- case 2: // fade out
- case 3: // forced fade out
+ case 2: // fade out
+ case 3: // forced fade out
menuTooltipAlpha = bound(0, menuTooltipAlpha - 2 * frametime, 1);
- if(menuTooltipAlpha == 0)
+ if (menuTooltipAlpha == 0)
{
menuTooltipState = 0;
menuTooltipItem = NULL;
break;
}
- if(menuTooltipItem == NULL)
+ if (menuTooltipItem == NULL)
{
if (menuTooltipText)
{
}
else
{
- if(menu_tooltips != menu_tooltips_old)
+ if (menu_tooltips != menu_tooltips_old)
{
- if (menu_tooltips != 0 && menu_tooltips_old != 0)
- menuTooltipItem = NULL; // reload tooltip next frame
+ if (menu_tooltips != 0 && menu_tooltips_old != 0) menuTooltipItem = NULL; // reload tooltip next frame
menu_tooltips_old = menu_tooltips;
}
- else if(menuTooltipOrigin.x < 0) // unallocated?
+ else if (menuTooltipOrigin.x < 0) // unallocated?
+ {
m_allocatetooltipbox(pos);
-
- if(menuTooltipOrigin.x >= 0)
+ }
+ if (menuTooltipOrigin.x >= 0)
{
// draw the tooltip!
- p = SKINBORDER_TOOLTIP;
+ vector p = SKINBORDER_TOOLTIP;
p.x *= 1 / conwidth;
p.y *= 1 / conheight;
draw_BorderPicture(menuTooltipOrigin, SKINGFX_TOOLTIP, menuTooltipSize, '1 1 1', menuTooltipAlpha, p);
p = menuTooltipOrigin;
p.x += SKINMARGIN_TOOLTIP_x / conwidth;
p.y += SKINMARGIN_TOOLTIP_y / conheight;
- getWrappedLine_remaining = menuTooltipText;
- while(getWrappedLine_remaining)
+ for (getWrappedLine_remaining = menuTooltipText; getWrappedLine_remaining; p.y += fontsize.y)
{
- s = getWrappedLine(SKINWIDTH_TOOLTIP, fontsize, draw_TextWidth_WithoutColors);
+ string s = getWrappedLine(SKINWIDTH_TOOLTIP, fontsize, draw_TextWidth_WithoutColors);
draw_Text(p, s, fontsize, SKINCOLOR_TOOLTIP, SKINALPHA_TOOLTIP * menuTooltipAlpha, false);
- p.y += fontsize.y;
}
}
}
void m_draw(float width, float height)
{
- float t;
- float realFrametime;
-
m_gamestatus();
execute_next_frame();
menuMouseMode = cvar("menu_mouse_absolute");
- if (anim)
- anim.tickAll(anim);
+ if (anim) anim.tickAll(anim);
UpdateConWidthHeight(width, height, cvar("vid_pixelheight"));
- if(!menuInitialized)
+ if (!menuInitialized)
{
// TODO draw an info image about this situation
m_init_delayed();
return;
}
- if(!menuNotTheFirstFrame)
+ if (!menuNotTheFirstFrame)
{
- menuNotTheFirstFrame = 1;
- if(Menu_Active)
- if(!cvar("menu_video_played"))
- {
- localcmd("cd loop $menu_cdtrack; play sound/announcer/default/welcome.wav\n");
- menuLogoAlpha = -0.8; // no idea why, but when I start this at zero, it jumps instead of fading FIXME
- }
+ menuNotTheFirstFrame = true;
+ if (Menu_Active && !cvar("menu_video_played"))
+ {
+ localcmd("cd loop $menu_cdtrack; play sound/announcer/default/welcome.wav\n");
+ menuLogoAlpha = -0.8; // no idea why, but when I start this at zero, it jumps instead of fading FIXME
+ }
// ALWAYS set this cvar; if we start but menu is not active, this means we want no background music!
localcmd("set menu_video_played 1\n");
}
- t = gettime();
- realFrametime = frametime = min(0.2, t - menuPrevTime);
+ float t = gettime();
+ float realFrametime = frametime = min(0.2, t - menuPrevTime);
menuPrevTime = t;
time += frametime;
t = cvar("menu_slowmo");
- if(t)
+ if (t)
{
frametime *= t;
realFrametime *= t;
}
else
+ {
t = 1;
+ }
- if(Menu_Active)
+ if (Menu_Active)
{
- if(getmousetarget() == (menuMouseMode ? MT_CLIENT : MT_MENU) && (getkeydest() == KEY_MENU || getkeydest() == KEY_MENU_GRABBED))
- setkeydest(keyGrabber ? KEY_MENU_GRABBED : KEY_MENU);
- else
- m_hide();
+ if (getmousetarget() == (menuMouseMode ? MT_CLIENT : MT_MENU)
+ && (getkeydest() == KEY_MENU || getkeydest() == KEY_MENU_GRABBED))
+ setkeydest(keyGrabber ? KEY_MENU_GRABBED : KEY_MENU);
+ else m_hide();
}
- if(cvar("cl_capturevideo"))
- frametime = t / cvar("cl_capturevideo_fps"); // make capturevideo work smoothly
+ if (cvar("cl_capturevideo")) frametime = t / cvar("cl_capturevideo_fps"); // make capturevideo work smoothly
prevMenuAlpha = menuAlpha;
- if(Menu_Active)
+ if (Menu_Active)
{
- if(menuAlpha == 0 && menuLogoAlpha < 2)
+ if (menuAlpha == 0 && menuLogoAlpha < 2)
{
- menuLogoAlpha = menuLogoAlpha + frametime * 2;
+ menuLogoAlpha += 2 * frametime;
}
else
{
- menuAlpha = min(1, menuAlpha + frametime * 5);
+ menuAlpha = min(1, menuAlpha + 5 * frametime);
menuLogoAlpha = 2;
}
}
else
{
- menuAlpha = max(0, menuAlpha - frametime * 5);
+ menuAlpha = max(0, menuAlpha - 5 * frametime);
menuLogoAlpha = 2;
}
draw_reset_cropped();
- if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER)))
+ if (!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER)))
{
- if(menuLogoAlpha > 0)
+ if (menuLogoAlpha > 0)
{
draw_reset_full();
draw_Fill('0 0 0', '1 1 0', SKINCOLOR_BACKGROUND, 1);
drawBackground(SKINGFX_BACKGROUND, bound(0, menuLogoAlpha, 1), SKINALIGN_BACKGROUND, true);
draw_reset_cropped();
- if(menuAlpha <= 0 && SKINALPHA_CURSOR_INTRO > 0)
+ if (menuAlpha <= 0 && SKINALPHA_CURSOR_INTRO > 0)
{
draw_alpha = SKINALPHA_CURSOR_INTRO * bound(0, menuLogoAlpha, 1);
draw_drawMousePointer(menuMousePos);
}
}
}
- else if(SKINALPHA_BACKGROUND_INGAME)
+ else if (SKINALPHA_BACKGROUND_INGAME)
{
- if(menuAlpha > 0)
+ if (menuAlpha > 0)
{
draw_reset_full();
- drawBackground(SKINGFX_BACKGROUND_INGAME, menuAlpha * SKINALPHA_BACKGROUND_INGAME, SKINALIGN_BACKGROUND_INGAME, false);
+ drawBackground(SKINGFX_BACKGROUND_INGAME, menuAlpha * SKINALPHA_BACKGROUND_INGAME,
+ SKINALIGN_BACKGROUND_INGAME, false);
draw_reset_cropped();
}
}
- if(menuAlpha != prevMenuAlpha)
- cvar_set("_menu_alpha", ftos(menuAlpha));
+ if (menuAlpha != prevMenuAlpha) cvar_set("_menu_alpha", ftos(menuAlpha));
draw_reset_cropped();
preMenuDraw();
draw_reset_cropped();
- if(menuAlpha <= 0)
+ if (menuAlpha <= 0)
{
- if(prevMenuAlpha > 0)
- main.initializeDialog(main, main.firstChild);
+ if (prevMenuAlpha > 0) main.initializeDialog(main, main.firstChild);
draw_reset_cropped();
postMenuDraw();
return;
draw_alpha *= menuAlpha;
- if(!Menu_Active)
+ if (!Menu_Active)
{
// do not update mouse position
// it prevents mouse jumping to '0 0 0' when menu is fading out
}
- else if(menuMouseMode)
+ else if (menuMouseMode)
{
- vector newMouse;
- newMouse = globalToBox(getmousepos(), draw_shift, draw_scale);
- if(newMouse != '0 0 0')
- if(newMouse != menuMousePos)
- {
- menuMousePos = newMouse;
- if(mouseButtonsPressed)
- main.mouseDrag(main, menuMousePos);
- else
- main.mouseMove(main, menuMousePos);
- }
+ vector newMouse = globalToBox(getmousepos(), draw_shift, draw_scale);
+ if (newMouse != '0 0 0' && newMouse != menuMousePos)
+ {
+ menuMousePos = newMouse;
+ if (mouseButtonsPressed) main.mouseDrag(main, menuMousePos);
+ else main.mouseMove(main, menuMousePos);
+ }
}
- else
+ else if (frametime > 0)
{
- if(frametime > 0)
+ vector dMouse = getmousepos() * (frametime / realFrametime); // for capturevideo
+ if (dMouse != '0 0 0')
{
- vector dMouse, minpos, maxpos;
- dMouse = getmousepos() * (frametime / realFrametime); // for capturevideo
- if(dMouse != '0 0 0')
- {
- minpos = globalToBox('0 0 0', draw_shift, draw_scale);
- maxpos = globalToBox(eX * (realconwidth - 1) + eY * (realconheight - 1), draw_shift, draw_scale);
- dMouse = globalToBoxSize(dMouse, draw_scale);
- menuMousePos += dMouse * cvar("menu_mouse_speed");
- menuMousePos.x = bound(minpos.x, menuMousePos.x, maxpos.x);
- menuMousePos.y = bound(minpos.y, menuMousePos.y, maxpos.y);
- if(mouseButtonsPressed)
- main.mouseDrag(main, menuMousePos);
- else
- main.mouseMove(main, menuMousePos);
- }
+ vector minpos = globalToBox('0 0 0', draw_shift, draw_scale);
+ vector maxpos = globalToBox(eX * (realconwidth - 1) + eY * (realconheight - 1), draw_shift, draw_scale);
+ dMouse = globalToBoxSize(dMouse, draw_scale);
+ menuMousePos += dMouse * cvar("menu_mouse_speed");
+ menuMousePos.x = bound(minpos.x, menuMousePos.x, maxpos.x);
+ menuMousePos.y = bound(minpos.y, menuMousePos.y, maxpos.y);
+ if (mouseButtonsPressed) main.mouseDrag(main, menuMousePos);
+ else main.mouseMove(main, menuMousePos);
}
}
main.draw(main);
setkeydest(KEY_MENU);
setmousetarget((menuMouseMode ? MT_CLIENT : MT_MENU));
- if(!menuInitialized)
- return;
+ if (!menuInitialized) return;
- if(mouseButtonsPressed)
- main.mouseRelease(main, menuMousePos);
+ if (mouseButtonsPressed) main.mouseRelease(main, menuMousePos);
mouseButtonsPressed = 0;
main.focusEnter(main);
setkeydest(KEY_GAME);
setmousetarget(MT_CLIENT);
- if(!menuInitialized)
- return;
+ if (!menuInitialized) return;
main.focusLeave(main);
main.hideNotify(main);
}
-void m_toggle(float mode)
+void m_toggle(int mode)
{
- if(Menu_Active)
+ if (Menu_Active)
{
- if (mode == 1)
- return;
+ if (mode == 1) return;
m_hide();
}
else
{
- if (mode == 0)
- return;
+ if (mode == 0) return;
m_display();
}
}
void Shutdown()
{
- entity e;
-
m_hide();
- for(e = NULL; (e = nextent(e)) != NULL; )
- {
- if(e.classname != "vtbl")
- if(e.destroy)
- e.destroy(e);
- }
+ FOREACH_ENTITY_ORDERED(it.destroy, LAMBDA(
+ if (it.classname == "vtbl") continue;
+ it.destroy(it);
+ ));
}
void m_focus_item_chain(entity outermost, entity innermost)
{
- if(innermost.parent != outermost)
- m_focus_item_chain(outermost, innermost.parent);
+ if (innermost.parent != outermost) m_focus_item_chain(outermost, innermost.parent);
innermost.parent.setFocus(innermost.parent, innermost);
}
void m_activate_window(entity wnd)
{
- entity par;
- par = wnd.parent;
- if(par)
- m_activate_window(par);
+ entity par = wnd.parent;
+ if (par) m_activate_window(par);
- if(par.instanceOfModalController)
+ if (par.instanceOfModalController)
{
- if(wnd.tabSelectingButton)
+ if (wnd.tabSelectingButton)
// tabs
TabButton_Click(wnd.tabSelectingButton, wnd);
else
// root
par.initializeDialog(par, wnd);
}
- else if(par.instanceOfNexposee)
+ else if (par.instanceOfNexposee)
{
// nexposee (sorry for violating abstraction here)
par.selectedChild = wnd;
par.animationState = 1;
Container_setFocus(par, NULL);
}
- else if(par.instanceOfContainer)
+ else if (par.instanceOfContainer)
{
// other containers
- if(par.focused)
- par.setFocus(par, wnd);
+ if (par.focused) par.setFocus(par, wnd);
}
}
void m_setpointerfocus(entity wnd)
{
- if(wnd.instanceOfContainer)
- {
- entity focus = wnd.preferredFocusedGrandChild(wnd);
- if(focus)
- {
- menuMousePos = focus.origin + 0.5 * focus.size;
- menuMousePos.x *= 1 / conwidth;
- menuMousePos.y *= 1 / conheight;
- entity par = wnd.parent;
- if(par.focused)
- par.setFocus(par, wnd);
- if(wnd.focused)
- m_focus_item_chain(wnd, focus);
- }
- }
+ if (!wnd.instanceOfContainer) return;
+ entity focus = wnd.preferredFocusedGrandChild(wnd);
+ if (!focus) return;
+ menuMousePos = focus.origin + 0.5 * focus.size;
+ menuMousePos.x *= 1 / conwidth;
+ menuMousePos.y *= 1 / conheight;
+ entity par = wnd.parent;
+ if (par.focused) par.setFocus(par, wnd);
+ if (wnd.focused) m_focus_item_chain(wnd, focus);
}
void m_goto(string itemname)
{
- entity e;
- if(!menuInitialized)
+ if (!menuInitialized)
{
- if(m_goto_buffer)
- strunzone(m_goto_buffer);
+ if (m_goto_buffer) strunzone(m_goto_buffer);
m_goto_buffer = strzone(itemname);
return;
}
- if(itemname == "") // this can be called by GameCommand
+ if (itemname == "") // this can be called by GameCommand
{
- if(gamestatus & (GAME_ISSERVER | GAME_CONNECTED))
+ if (gamestatus & (GAME_ISSERVER | GAME_CONNECTED))
{
m_hide();
}
}
else
{
- for(e = NULL; (e = find(e, name, itemname)); )
- if(e.classname != "vtbl")
- break;
+ entity e;
+ for (e = NULL; (e = find(e, name, itemname)); )
+ if (e.classname != "vtbl") break;
- if((e) && (!e.requiresConnection || (gamestatus & (GAME_ISSERVER | GAME_CONNECTED))))
+ if ((e) && (!e.requiresConnection || (gamestatus & (GAME_ISSERVER | GAME_CONNECTED))))
{
m_hide();
m_activate_window(e);
}
}
-float menuLastFocusSoundTime;
void m_play_focus_sound()
{
- if(cvar("menu_sounds") > 1)
- if(time - menuLastFocusSoundTime > 0.25)
- {
- localsound(MENU_SOUND_FOCUS);
- menuLastFocusSoundTime = time;
- }
+ static float menuLastFocusSoundTime;
+ if (cvar("menu_sounds") < 2) return;
+ if (time - menuLastFocusSoundTime <= 0.25) return;
+ localsound(MENU_SOUND_FOCUS);
+ menuLastFocusSoundTime = time;
}
void m_play_click_sound(string soundfile)
{
- if(cvar("menu_sounds"))
- localsound(soundfile);
+ if (!cvar("menu_sounds")) return;
+ localsound(soundfile);
}
#include "../common/constants.qh"
#include "../common/util.qh"
-// constants
+const int GAME_ISSERVER = BIT(0);
+const int GAME_CONNECTED = BIT(1);
+const int GAME_DEVELOPER = BIT(2);
-const int GAME_ISSERVER = 1;
-const int GAME_CONNECTED = 2;
-const int GAME_DEVELOPER = 4;
-
-// prototypes
-
-float Menu_Active;
+bool Menu_Active;
int gamestatus;
const int S_SHIFT = 1;
.string name;
entity keyGrabber;
-.void(entity me, float key, float ascii) keyGrabbed;
+.void(entity this, float key, float ascii) keyGrabbed;
-float conwidth, conheight; // "virtual" conwidth/height values for other stuff to assume for scaling
+// "virtual" conwidth/height values for other stuff to assume for scaling
+float conwidth, conheight;
-float preMenuInit(); // you have to define this for pre-menu initialization. Return 0 if initialization needs to be retried a frame later, 1 if it succeeded.
-void preMenuDraw(); // this is run before the menu is drawn. You may put some stuff there that has to be done every frame.
-void postMenuDraw(); // this is run just after the menu is drawn (or not). Useful to draw something over everything else.
+/** you have to define this for pre-menu initialization. Return 0 if initialization needs to be retried a frame later, 1 if it succeeded. */
+float preMenuInit();
+/** this is run before the menu is drawn. You may put some stuff there that has to be done every frame. */
+void preMenuDraw();
+/** this is run just after the menu is drawn (or not). Useful to draw something over everything else. */
+void postMenuDraw();
void m_sync();
void draw_reset_cropped();
-// sounds
-
const string MENU_SOUND_CLEAR = "sound/menu/clear.wav";
const string MENU_SOUND_CLOSE = "sound/menu/close.wav";
const string MENU_SOUND_EXECUTE = "sound/menu/execute.wav";
+++ /dev/null
-#ifndef SYS_POST_H
-#define SYS_POST_H
-
-#pragma noref 0
-#endif
+++ /dev/null
-#ifndef SYS_PRE_H
-#define SYS_PRE_H
-
-#pragma noref 1
-#endif
void XonoticCrosshairPicker_cellDraw(entity me, vector cell, vector cellPos)
{
- vector sz;
- string cross = strcat("/gfx/crosshair", crosshairpicker_cellToCrosshair(me, cell));
- sz = draw_PictureSize(cross);
+ string s = strcat("/gfx/crosshair", crosshairpicker_cellToCrosshair(me, cell));
+ vector sz = draw_PictureSize(s);
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;
+ sz *= 0.95;
vector crosshairPos = cellPos + 0.5 * me.realCellSize;
- draw_Picture(crosshairPos - 0.5 * sz, cross, sz, SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
+ draw_Picture(crosshairPos - 0.5 * sz, s, 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);
#ifdef IMPLEMENTATION
-void GameType_ConfigureSliders(entity e, entity l, string pLabel, float pMin, float pMax, float pStep, string pCvar, string theTooltip)
+void GameType_ConfigureSliders(entity me, string pLabel, float pMin, float pMax, float pStep, string pCvar, string tCvar, string pTooltip)
{
- if(pCvar == "")
+ int i;
+ entity e = me.sliderFraglimit;
+ entity l = me.labelFraglimit;
+ e.configureXonoticTextSlider(e, pCvar, pTooltip);
+ e.disabled = l.disabled = !pCvar;
+ l.setText(l, pLabel);
+
+ // clear old values
+ for(i = 0; i < e.nValues; ++i);
{
- e.configureXonoticTextSlider(e, string_null, string_null);
- l.setText(l, pLabel);
- e.disabled = l.disabled = true;
- }
- else
- {
- e.configureXonoticTextSlider(e, pCvar, theTooltip);
-
- // clear old values
- int i;
- for(i = 0; i <= e.nValues; ++i);
+ if(e.(valueStrings[i]))
+ {
+ strunzone(e.(valueStrings[i]));
+ e.(valueStrings[i]) = string_null;
+ }
+ if(e.(valueIdentifiers[i]))
{
- if(e.(valueStrings[i])) { strunzone(e.(valueStrings[i])); }
- if(e.(valueIdentifiers[i])) { strunzone(e.(valueIdentifiers[i])); }
+ strunzone(e.(valueIdentifiers[i]));
+ e.(valueIdentifiers[i]) = string_null;
}
- e.clearValues(e);
+ }
+ e.clearValues(e);
+ if(pCvar != "")
+ {
// set new values
e.addValue(e, strzone(_("Default")), strzone("-1"));
for(i = pMin; i <= pMax; i += pStep) { e.addValue(e, strzone(ftos(i)), strzone(ftos(i))); }
e.addValue(e, strzone(_("Unlimited")), strzone("0"));
- e.configureXonoticTextSliderValues(e);
-
- // set text field
- l.setText(l, pLabel);
- e.disabled = l.disabled = false;
}
+ e.configureXonoticTextSliderValues(e);
+
+
+ entity t = me.sliderTeams;
+ entity tl = me.labelTeams;
+ t.configureXonoticTextSlider(t, tCvar, string_null);
+ tl.disabled = t.disabled = !tCvar;
+ t.nValues = (tCvar == "") ? 0 : 4; // instead of clearing / readding the very same values
+ t.configureXonoticTextSliderValues(t);
}
entity makeXonoticServerCreateTab()
void XonoticServerCreateTab_gameTypeChangeNotify(entity me)
{
- // tell the map list to update
- float gt;
- entity e, l;
- gt = MapInfo_CurrentGametype();
- e = me.sliderFraglimit;
- l = me.labelFraglimit;
-
- switch(gt)
+ switch(MapInfo_CurrentGametype())
{
- case MAPINFO_TYPE_CTF: GameType_ConfigureSliders(e, l, _("Capture limit:"), 1, 20, 1, "capturelimit_override", string_null); break;
- case MAPINFO_TYPE_DOMINATION: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, "g_domination_point_limit", string_null); break;
- case MAPINFO_TYPE_KEYHUNT: GameType_ConfigureSliders(e, l, _("Point limit:"), 200, 1500, 50, "g_keyhunt_point_limit", string_null); break;
- case MAPINFO_TYPE_LMS: GameType_ConfigureSliders(e, l, _("Lives:"), 3, 50, 1, "g_lms_lives_override", string_null); break;
- case MAPINFO_TYPE_RACE: GameType_ConfigureSliders(e, l, _("Laps:"), 1, 25, 1, "g_race_laps_limit", string_null); break;
- case MAPINFO_TYPE_NEXBALL: GameType_ConfigureSliders(e, l, _("Goals:"), 1, 50, 1, "g_nexball_goallimit", string_null); break;
- case MAPINFO_TYPE_ASSAULT: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, "", string_null); break;
- case MAPINFO_TYPE_ONSLAUGHT: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, "", string_null); break;
- case MAPINFO_TYPE_CTS: GameType_ConfigureSliders(e, l, _("Point limit:"), 50, 500, 10, "", string_null); break;
- case MAPINFO_TYPE_INVASION: GameType_ConfigureSliders(e, l, _("Point limit:"), 5, 0, 5, "", string_null); break;
- case MAPINFO_TYPE_TEAM_DEATHMATCH:GameType_ConfigureSliders(e, l, _("Point limit:"), 5, 100, 5, "g_tdm_point_limit", string_null); break;
- default: GameType_ConfigureSliders(e, l, _("Frag limit:"), 5, 100, 5, "fraglimit_override", _("The amount of frags needed before the match will end")); break;
+ case MAPINFO_TYPE_CA: GameType_ConfigureSliders(me, _("Frag limit:"), 5, 100, 5, "fraglimit_override", "g_ca_teams_override", _("The amount of frags needed before the match will end")); break;
+ case MAPINFO_TYPE_FREEZETAG: GameType_ConfigureSliders(me, _("Frag limit:"), 5, 100, 5, "fraglimit_override", "g_freezetag_teams_override", _("The amount of frags needed before the match will end")); break;
+ case MAPINFO_TYPE_CTF: GameType_ConfigureSliders(me, _("Capture limit:"), 1, 20, 1, "capturelimit_override", string_null, _("The amount of captures needed before the match will end")); break;
+ case MAPINFO_TYPE_DOMINATION: GameType_ConfigureSliders(me, _("Point limit:"), 50, 500, 10, "g_domination_point_limit", "g_domination_teams_override", _("The amount of points needed before the match will end")); break;
+ case MAPINFO_TYPE_KEYHUNT: GameType_ConfigureSliders(me, _("Point limit:"), 200, 1500, 50, "g_keyhunt_point_limit", "g_keyhunt_teams_override", _("The amount of points needed before the match will end")); break;
+ case MAPINFO_TYPE_LMS: GameType_ConfigureSliders(me, _("Lives:"), 3, 50, 1, "g_lms_lives_override", string_null, string_null); break;
+ case MAPINFO_TYPE_RACE: GameType_ConfigureSliders(me, _("Laps:"), 1, 25, 1, "g_race_laps_limit", string_null, string_null); break;
+ case MAPINFO_TYPE_NEXBALL: GameType_ConfigureSliders(me, _("Goals:"), 1, 50, 1, "g_nexball_goallimit", string_null, _("The amount of goals needed before the match will end")); break;
+ case MAPINFO_TYPE_ASSAULT: GameType_ConfigureSliders(me, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null); break;
+ case MAPINFO_TYPE_ONSLAUGHT: GameType_ConfigureSliders(me, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null); break;
+ case MAPINFO_TYPE_CTS: GameType_ConfigureSliders(me, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null); break;
+ case MAPINFO_TYPE_INVASION: GameType_ConfigureSliders(me, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null); break;
+ case MAPINFO_TYPE_TEAM_DEATHMATCH: GameType_ConfigureSliders(me, _("Point limit:"), 5, 100, 5, "g_tdm_point_limit", "g_tdm_teams_override", _("The amount of points needed before the match will end")); break;
+ default: GameType_ConfigureSliders(me, _("Frag limit:"), 5, 100, 5, "fraglimit_override", string_null, _("The amount of frags needed before the match will end")); break;
}
- string x = string_null;
- string theTooltip = string_null;
- e = me.sliderTeams;
- switch(gt)
- {
- // old tooltip: _("Override the default amount of teams in teamgames")
- case MAPINFO_TYPE_CA: x = "g_ca_teams_override"; break;
- case MAPINFO_TYPE_DOMINATION: x = "g_domination_teams_override"; break;
- case MAPINFO_TYPE_FREEZETAG: x = "g_freezetag_teams_override"; break;
- case MAPINFO_TYPE_KEYHUNT: x = "g_keyhunt_teams_override"; break;
- case MAPINFO_TYPE_TEAM_DEATHMATCH: x = "g_tdm_teams_override"; break;
- }
- e.configureXonoticTextSlider(e, x, theTooltip);
- e.configureXonoticTextSliderValues(e);
- me.sliderTeams.disabled = me.labelTeams.disabled = !x;
-
me.mapListBox.refilter(me.mapListBox);
}
me.currentServerNumFreeSlots = strzone(s);
me.numFreeSlotsLabel.setText(me.numFreeSlotsLabel, me.currentServerNumFreeSlots);
- me.currentServerMod = ((modname == "Xonotic") ? _("Default") : modname);
+ me.currentServerMod = ((modname == "Xonotic") ? ZCTX(_("MOD^Default")) : modname);
me.currentServerMod = strzone(me.currentServerMod);
me.modLabel.setText(me.modLabel, me.currentServerMod);
#endif
me.gotoRC(me, me.rows - 1, 0);
- me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "color -1 -1;name \"$_cl_name\";sendcvar cl_weaponpriority;sendcvar cl_autoswitch;sendcvar cl_forceplayermodels;sendcvar cl_forceplayermodelsfromxonotic;playermodel $_cl_playermodel;playerskin $_cl_playerskin", COMMANDBUTTON_APPLY));
+ me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "color -1 -1;name \"$_cl_name\";sendcvar cl_autoswitch;sendcvar cl_forceplayermodels;sendcvar cl_forceplayermodelsfromxonotic;playermodel $_cl_playermodel;playerskin $_cl_playerskin", COMMANDBUTTON_APPLY));
}
#endif
float n;
me.TR(me);
me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Quality preset:")));
- n = 5 + 2 * !!cvar("developer");
+ n = 5 + 2 * boolean(cvar("developer"));
if(cvar("developer"))
me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^OMG!")), '1 0 1', "exec effects-omg.cfg", 0));
me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Low")), '0 0 0', "exec effects-low.cfg", 0));
topics.onChangeEntity = this;
int
- col = 0, width = 1.5;
+ col = 0, width = 1;
this.gotoRC(this, 0, col);
this.TD(this, this.rows, width, topics);
float teams, nTeams;
teams = cvar("_teams_available");
nTeams = 0;
- me.team1.disabled = !(teams & 1); nTeams += !!(teams & 1);
- me.team2.disabled = !(teams & 2); nTeams += !!(teams & 2);
- me.team3.disabled = !(teams & 4); nTeams += !!(teams & 4);
- me.team4.disabled = !(teams & 8); nTeams += !!(teams & 8);
+ me.team1.disabled = !(teams & 1); nTeams += boolean(teams & 1);
+ me.team2.disabled = !(teams & 2); nTeams += boolean(teams & 2);
+ me.team3.disabled = !(teams & 4); nTeams += boolean(teams & 4);
+ me.team4.disabled = !(teams & 8); nTeams += boolean(teams & 8);
}
void XonoticTeamSelectDialog_fill(entity me)
continue;
bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_ID, argv(0));
bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_NAME, argv(1));
- float k = strstrofs(argv(2), "(", 0);
- if(k > 0)
- if(substring(argv(2), strlen(argv(2)) - 1, 1) == ")")
- {
- string percent = substring(argv(2), k + 1, -2);
- if(percent != "100%")
- bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_PERCENTAGE, percent);
- }
- bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_NAME_LOCALIZED, (k < 0) ? argv(2) : substring(argv(2), 0, k - 1));
+ bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_NAME_LOCALIZED, argv(2));
+ string percent = argv(3);
+ if(percent && percent != "100%")
+ bufstr_set(buf, i * LANGPARM_COUNT + LANGPARM_PERCENTAGE, percent);
++i;
}
fclose(fh);
{
if(me.cvarName)
{
- me.checked = !!cvar(me.cvarName);
+ me.checked = boolean(cvar(me.cvarName));
}
else
{
METHOD(XonoticServerList, toggleFavorite, void(entity, string));
ATTRIB(XonoticServerList, iconsSizeFactor, float, 0.85)
+ METHOD(XonoticServerList, mouseMove, float(entity, vector));
+ ATTRIB(XonoticServerList, mouseOverIcons, bool, false)
+ METHOD(XonoticServerList, focusedItemChangeNotify, void(entity));
ATTRIB(XonoticServerList, realFontSize, vector, '0 0 0')
ATTRIB(XonoticServerList, realUpperMargin, float, 0)
#ifdef COMPAT_NO_MOD_IS_XONOTIC
if(modname == "")
- modname = "xonotic";
+ modname = "Xonotic";
#endif
+ string original_modname = modname;
modname = strtolower(modname);
/*
if(modname != "cts")
if(modname != "nix")
if(modname != "newtoys")
- pure = false;
+ pure_available = false;
if(gethostcachenumber(SLIST_FIELD_FREESLOTS, i) <= 0)
theAlpha = SKINALPHA_SERVERLIST_FULL;
if(sflags >= 0 && (sflags & SERVERFLAG_PLAYERSTATS))
draw_Picture(iconPos, "icon_stats1", iconSize, '1 1 1', 1);
+ if(isFocused && me.mouseOverIcons && !me.tooltip)
+ {
+ string t = "";
+ if(me.seenIPv4 && me.seenIPv6)
+ t = strcat(t, (isv6) ? "IPv6, " : "IPv4, ");
+ t = strcat(t, _("encryption:"), " ", (q ? sprintf(_("AES level %d"), q) : ZCTX(_("ENC^none"))), ", ");
+ t = strcat(t, sprintf(_("mod: %s"), ((modname == "xonotic") ? ZCTX(_("MOD^Default")) : original_modname)));
+ if(pure_available)
+ t = strcat(t, sprintf(_(" (%s)"), (pure) ? _("official settings") : _("modified settings")));
+ t = strcat(t, ", ");
+ t = strcat(t, ((sflags >= 0 && (sflags & SERVERFLAG_PLAYERSTATS)) ? _("stats enabled") : _("stats disabled")));
+ setZonedTooltip(me, t, string_null);
+ }
// --------------
// RENDER TEXT
// --------------
draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
}
+void XonoticServerList_focusedItemChangeNotify(entity me)
+{
+ clearTooltip(me);
+}
+
+float XonoticServerList_mouseMove(entity me, vector pos)
+{
+ if(!SUPER(XonoticServerList).mouseMove(me, pos))
+ {
+ me.mouseOverIcons = false;
+ clearTooltip(me);
+ return 1;
+ }
+
+ me.mouseOverIcons = (pos_x <= me.columnIconsSize);
+ if(!me.mouseOverIcons)
+ clearTooltip(me);
+ return 1;
+}
+
bool XonoticServerList_keyDown(entity me, int scan, bool ascii, bool shift)
{
vector org, sz;
void saveCvarsMulti(entity me)
{
float n, i;
- string s;
+ string s, cvarname;
me.saveCvars_Multi(me);
s = cvar_string(me.cvarName);
n = tokenize_console(me.cvarNames_Multi);
for(i = 0; i < n; ++i)
{
+ // cvars prefixed with ! get saved with the inverted value
if(substring(argv(i), 0, 1) == "!")
- cvar_set(substring(argv(i), 1, strlen(argv(i))), ((s == "0") ? "1" : "0"));
+ {
+ cvarname = substring(argv(i), 1, strlen(argv(i)));
+ cvar_set(cvarname, ((s == "0") ? "1" : "0"));
+ }
else
- cvar_set(argv(i), s);
+ {
+ cvarname = argv(i);
+ cvar_set(cvarname, s);
+ }
- CheckSendCvars(me, argv(i));
+ CheckSendCvars(me, cvarname);
}
}
void makeMulti(entity e, string otherCvars)
#ifndef SERVER_ALL_H
#define SERVER_ALL_H
+int maxclients;
+
+const string STR_PLAYER = "player";
+const string STR_SPECTATOR = "spectator";
+const string STR_OBSERVER = "observer";
+
+#define IS_PLAYER(v) ((v).classname == STR_PLAYER)
+#define IS_SPEC(v) ((v).classname == STR_SPECTATOR)
+#define IS_OBSERVER(v) ((v).classname == STR_OBSERVER)
+
+#define IS_CLIENT(v) (v.flags & FL_CLIENT)
+#define IS_BOT_CLIENT(v) (clienttype(v) == CLIENTTYPE_BOT)
+#define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL)
+#define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT)
+
+#define IS_MONSTER(v) (v.flags & FL_MONSTER)
+#define IS_VEHICLE(v) (v.vehicle_flags & VHF_ISVEHICLE)
+#define IS_TURRET(v) (v.turret_flags & TUR_FLAG_ISTURRET)
+
+#define FOR_EACH_CLIENTSLOT(v) for (v = world; (v = nextent(v)) && (num_for_edict(v) <= maxclients); )
+#define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if (IS_CLIENT(v))
+#define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if (IS_REAL_CLIENT(v))
+
+#define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if (IS_PLAYER(v))
+#define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if (IS_SPEC(v))
+#define FOR_EACH_OBSERVER(v) FOR_EACH_CLIENT(v) if (IS_OBSERVER(v))
+#define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if (IS_PLAYER(v))
+
+#define FOR_EACH_MONSTER(v) for (v = world; (v = findflags(v, flags, FL_MONSTER)) != world; )
+
#include "../common/effects/all.qh"
#include "../common/models/all.qh"
#include "../common/sounds/all.qh"
bool autocvar_bot_nofire;
#define autocvar_bot_number cvar("bot_number")
#define autocvar_bot_prefix cvar_string("bot_prefix")
-bool autocvar_bot_sound_monopoly;
#define autocvar_bot_suffix cvar_string("bot_suffix")
bool autocvar_bot_usemodelnames;
int autocvar_bot_vs_human;
float autocvar_sv_gameplayfix_gravityunaffectedbyticrate;
bool autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag;
float autocvar_g_trueaim_minrange;
-bool autocvar_g_debug_defaultsounds;
float autocvar_g_grab_range;
int autocvar_g_max_info_autoscreenshot;
bool autocvar_physics_ode;
for (int i = WEP_FIRST; i <= WEP_LAST; ++i)
{
entity e = get_weaponinfo(i);
- if ((self.weapons & WepSet_FromWeapon(i)) && (e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < e.reloading_ammo))
+ if ((self.weapons & (e.m_wepset)) && (e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < e.reloading_ammo))
self.switchweapon = i;
}
}
}
// Keep pressing keys raised by the "presskey" command
- ispressingkey = !!bot_presskeys();
+ ispressingkey = boolean(bot_presskeys());
// Handle conditions
if (!(bot_cmd.bot_cmd_type==BOT_CMD_FI||bot_cmd.bot_cmd_type==BOT_CMD_ELSE))
#include "anticheat.qh"
#include "cl_impulse.qh"
#include "cl_player.qh"
-#include "ent_cs.qh"
#include "ipban.qh"
#include "miscfunctions.qh"
#include "portals.qh"
#include "bot/bot.qh"
#include "bot/navigation.qh"
+#include "../common/ent_cs.qh"
#include "../common/vehicles/all.qh"
#include "../common/triggers/teleporters.qh"
precache_model(modelname);
_setmodel(e, modelname);
player_setupanimsformodel();
- UpdatePlayerSounds();
}
/*
self.event_damage = func_null;
}
+int player_getspecies(entity this)
+{
+ get_model_parameters(this.model, this.skin);
+ int s = get_model_parameters_species;
+ get_model_parameters(string_null, 0);
+ if (s < 0) return SPECIES_HUMAN;
+ return s;
+}
+
.float model_randomizer;
void FixPlayermodel(entity player)
{
if(chmdl || oldskin != player.skin) // model or skin has changed
{
- player.species = player_getspecies(); // update species
- UpdatePlayerSounds(); // update skin sounds
+ player.species = player_getspecies(player); // update species
}
if(!teamplay)
else
stuffcmd(self, "set _teams_available 0\n");
- attach_entcs(self);
+ entcs_attach(self);
bot_relinkplayerlist();
self.model_randomizer = random();
if(IS_REAL_CLIENT(self))
- sv_notice_join();
+ sv_notice_join(self);
for (entity e = world; (e = findfloat(e, init_for_player_needed, 1)); ) {
WITH(entity, self, e, e.init_for_player(this));
bot_clientdisconnect();
- detach_entcs(self);
+ entcs_detach(self);
if(autocvar_sv_eventlog)
GameLogEcho(strcat(":part:", ftos(self.playerid)));
if(self.weaponorder_byimpulse)
strunzone(self.weaponorder_byimpulse);
- ClearPlayerSounds();
-
if(self.personal)
remove(self.personal);
// weapon switching impulses
if(self.deadflag == DEAD_NO)
W_NextWeaponOnImpulse(imp);
- //else
+ //else // don't retry, as this can break weaplast bind
// self.impulse = imp; // retry in next frame
}
else if(imp >= 10 && imp <= 20)
break;
}
}
- //else
+ //else // don't retry, as this can break weaplast bind
//self.impulse = imp; // retry in next frame
}
else if(imp == 21)
m = (imp - (210 + i)); // <0 for prev, =0 for best, >0 for next
W_CycleWeapon(self.(cvar_cl_weaponpriorities[i]), m);
}
- //else
+ //else // don't retry, as this can break weaplast bind
//self.impulse = imp; // retry in next frame
}
else if(imp >= WEP_IMPULSE_BEGIN && imp <= WEP_IMPULSE_END)
if(!self.vehicle)
if(self.deadflag == DEAD_NO)
W_SwitchWeapon (imp - WEP_IMPULSE_BEGIN + WEP_FIRST);
- //else
+ //else // don't retry, as this can break weaplast bind
//self.impulse = imp; // retry in next frame
}
// deploy waypoints
setself(this);
}
-float player_getspecies()
-{SELFPARAM();
- float s;
- get_model_parameters(self.model, self.skin);
- s = get_model_parameters_species;
- get_model_parameters(string_null, 0);
- if(s < 0)
- return SPECIES_HUMAN;
- return s;
-}
-
void player_setupanimsformodel()
{SELFPARAM();
// load animation info
PlayerScore_Add(self, SP_DMGTAKEN, realdmg);
}
}
-
+
bool abot = (IS_BOT_CLIENT(attacker));
bool vbot = (IS_BOT_CLIENT(self));
}
}
-float Say(entity source, float teamsay, entity privatesay, string msgin, float floodcontrol)
-// message "": do not say, just test flood control
-// return value:
-// 1 = accept
-// 0 = reject
-// -1 = fake accept
+void MoveToTeam(entity client, int team_colour, int type)
+{
+ int lockteams_backup = lockteams; // backup any team lock
+ lockteams = 0; // disable locked teams
+ TeamchangeFrags(client); // move the players frags
+ SetPlayerColors(client, team_colour - 1); // set the players colour
+ Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, client.origin, '0 0 0'); // kill the player
+ lockteams = lockteams_backup; // restore the team lock
+ LogTeamchange(client.playerid, client.team, type);
+}
+
+/**
+ * message "": do not say, just test flood control
+ * return value:
+ * 1 = accept
+ * 0 = reject
+ * -1 = fake accept
+ */
+int Say(entity source, float teamsay, entity privatesay, string msgin, bool floodcontrol)
{
string msgstr, colorstr, cmsgstr, namestr, fullmsgstr, sourcemsgstr, fullcmsgstr, sourcecmsgstr, colorprefix;
float flood;
return ret;
}
-
-float GetVoiceMessageVoiceType(string type)
-{
- if(type == "taunt")
- return VOICETYPE_TAUNT;
- if(type == "teamshoot")
- return VOICETYPE_LASTATTACKER;
- return VOICETYPE_TEAMRADIO;
-}
-
-.string GetVoiceMessageSampleField(string type)
-{
- GetPlayerSoundSampleField_notFound = 0;
- switch(type)
- {
-#define _VOICEMSG(m) case #m: return playersound_##m;
- ALLVOICEMSGS
-#undef _VOICEMSG
- }
- GetPlayerSoundSampleField_notFound = 1;
- return playersound_taunt;
-}
-
-.string GetPlayerSoundSampleField(string type)
-{
- GetPlayerSoundSampleField_notFound = 0;
- switch(type)
- {
-#define _VOICEMSG(m) case #m: return playersound_##m;
- ALLPLAYERSOUNDS
-#undef _VOICEMSG
- }
- GetPlayerSoundSampleField_notFound = 1;
- return playersound_taunt;
-}
-
-void PrecacheGlobalSound(string samplestring)
-{
- float n, i;
- tokenize_console(samplestring);
- n = stof(argv(1));
- if(n > 0)
- {
- for(i = 1; i <= n; ++i)
- precache_sound(strcat(argv(0), ftos(i), ".wav"));
- }
- else
- {
- precache_sound(strcat(argv(0), ".wav"));
- }
-}
-
-void PrecachePlayerSounds(string f)
-{
- int fh = fopen(f, FILE_READ);
- if (fh < 0)
- return;
- for (string s; (s = fgets(fh)); )
- {
- int n = tokenize_console(s);
- if (n != 3)
- {
- if (n != 0) LOG_TRACEF("Invalid sound info line: %s\n", s);
- continue;
- }
- PrecacheGlobalSound(strcat(argv(1), " ", argv(2)));
- }
- fclose(fh);
-
- if (!allvoicesamples)
- {
-#define _VOICEMSG(m) allvoicesamples = strcat(allvoicesamples, " ", #m);
- ALLVOICEMSGS
-#undef _VOICEMSG
- allvoicesamples = strzone(substring(allvoicesamples, 1, strlen(allvoicesamples) - 1));
- }
-}
-
-void ClearPlayerSounds()
-{SELFPARAM();
-#define _VOICEMSG(m) if(self.playersound_##m) { strunzone(self.playersound_##m); self.playersound_##m = string_null; }
- ALLPLAYERSOUNDS
- ALLVOICEMSGS
-#undef _VOICEMSG
-}
-
-float LoadPlayerSounds(string f, float first)
-{SELFPARAM();
- float fh;
- string s;
- var .string field;
- fh = fopen(f, FILE_READ);
- if(fh < 0)
- {
- LOG_TRACE("Player sound file not found: ", f, "\n");
- return 0;
- }
- while((s = fgets(fh)))
- {
- if(tokenize_console(s) != 3)
- continue;
- field = GetPlayerSoundSampleField(argv(0));
- if(GetPlayerSoundSampleField_notFound)
- field = GetVoiceMessageSampleField(argv(0));
- if(GetPlayerSoundSampleField_notFound)
- continue;
- if (self.(field))
- strunzone(self.(field));
- self.(field) = strzone(strcat(argv(1), " ", argv(2)));
- }
- fclose(fh);
- return 1;
-}
-
-void UpdatePlayerSounds()
-{SELFPARAM();
- if(self.modelindex == self.modelindex_for_playersound)
- if(self.skin == self.skin_for_playersound)
- return;
- self.modelindex_for_playersound = self.modelindex;
- self.skin_for_playersound = self.skin;
- ClearPlayerSounds();
- LoadPlayerSounds("sound/player/default.sounds", 1);
- if(!autocvar_g_debug_defaultsounds)
- if(!LoadPlayerSounds(get_model_datafilename(self.model, self.skin, "sounds"), 0))
- LoadPlayerSounds(get_model_datafilename(self.model, 0, "sounds"), 0);
-}
-
-void FakeGlobalSound(string sample, float chan, float voicetype)
-{SELFPARAM();
- float n;
- float tauntrand;
-
- if(sample == "")
- return;
-
- tokenize_console(sample);
- n = stof(argv(1));
- if(n > 0)
- sample = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization
- else
- sample = strcat(argv(0), ".wav"); // randomization
-
- switch(voicetype)
- {
- case VOICETYPE_LASTATTACKER_ONLY:
- break;
- case VOICETYPE_LASTATTACKER:
- if(self.pusher)
- {
- msg_entity = self;
- if(IS_REAL_CLIENT(msg_entity))
- soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_TEAMRADIO:
- msg_entity = self;
- if(msg_entity.cvar_cl_voice_directional == 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN);
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- break;
- case VOICETYPE_AUTOTAUNT:
- if(!sv_autotaunt)
- break;
- if(!sv_taunt)
- break;
- if(autocvar_sv_gentle)
- break;
- tauntrand = random();
- msg_entity = self;
- if (tauntrand < msg_entity.cvar_cl_autotaunt)
- {
- if (msg_entity.cvar_cl_voice_directional >= 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX));
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_TAUNT:
- if(IS_PLAYER(self))
- if(self.deadflag == DEAD_NO)
- animdecide_setaction(self, ANIMACTION_TAUNT, true);
- if(!sv_taunt)
- break;
- if(autocvar_sv_gentle)
- break;
- msg_entity = self;
- if (msg_entity.cvar_cl_voice_directional >= 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX));
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- break;
- case VOICETYPE_PLAYERSOUND:
- msg_entity = self;
- soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NORM);
- break;
- default:
- backtrace("Invalid voice type!");
- break;
- }
-}
-
-void GlobalSound(string sample, float chan, float voicetype)
-{SELFPARAM();
- float n;
- float tauntrand;
-
- if(sample == "")
- return;
-
- tokenize_console(sample);
- n = stof(argv(1));
- if(n > 0)
- sample = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization
- else
- sample = strcat(argv(0), ".wav"); // randomization
-
- switch(voicetype)
- {
- case VOICETYPE_LASTATTACKER_ONLY:
- if(self.pusher)
- {
- msg_entity = self.pusher;
- if(IS_REAL_CLIENT(msg_entity))
- {
- if(msg_entity.cvar_cl_voice_directional == 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN);
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- }
- break;
- case VOICETYPE_LASTATTACKER:
- if(self.pusher)
- {
- msg_entity = self.pusher;
- if(IS_REAL_CLIENT(msg_entity))
- {
- if(msg_entity.cvar_cl_voice_directional == 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN);
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- msg_entity = self;
- if(IS_REAL_CLIENT(msg_entity))
- soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_TEAMRADIO:
- FOR_EACH_REALCLIENT(msg_entity)
- if(!teamplay || msg_entity.team == self.team)
- {
- if(msg_entity.cvar_cl_voice_directional == 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN);
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_AUTOTAUNT:
- if(!sv_autotaunt)
- break;
- if(!sv_taunt)
- break;
- if(autocvar_sv_gentle)
- break;
- tauntrand = random();
- FOR_EACH_REALCLIENT(msg_entity)
- if (tauntrand < msg_entity.cvar_cl_autotaunt)
- {
- if (msg_entity.cvar_cl_voice_directional >= 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX));
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_TAUNT:
- if(IS_PLAYER(self))
- if(self.deadflag == DEAD_NO)
- animdecide_setaction(self, ANIMACTION_TAUNT, true);
- if(!sv_taunt)
- break;
- if(autocvar_sv_gentle)
- break;
- FOR_EACH_REALCLIENT(msg_entity)
- {
- if (msg_entity.cvar_cl_voice_directional >= 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX));
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_PLAYERSOUND:
- _sound(self, chan, sample, VOL_BASE, ATTEN_NORM);
- break;
- default:
- backtrace("Invalid voice type!");
- break;
- }
-}
-
-void PlayerSound(.string samplefield, float chan, float voicetype)
-{SELFPARAM();
- GlobalSound(self.(samplefield), chan, voicetype);
-}
-
-void VoiceMessage(string type, string msg)
-{SELFPARAM();
- float voicetype, ownteam;
- float flood;
- var .string sample = GetVoiceMessageSampleField(type);
-
- if(GetPlayerSoundSampleField_notFound)
- {
- sprint(self, strcat("Invalid voice. Use one of: ", allvoicesamples, "\n"));
- return;
- }
-
- voicetype = GetVoiceMessageVoiceType(type);
- ownteam = (voicetype == VOICETYPE_TEAMRADIO);
-
- flood = Say(self, ownteam, world, msg, 1);
-
- if (IS_SPEC(self) || IS_OBSERVER(self) || flood < 0)
- FakeGlobalSound(self.(sample), CH_VOICE, voicetype);
- else if (flood > 0)
- GlobalSound(self.(sample), CH_VOICE, voicetype);
-}
-
-void MoveToTeam(entity client, float team_colour, float type)
-{
- float lockteams_backup;
-
- lockteams_backup = lockteams; // backup any team lock
-
- lockteams = 0; // disable locked teams
-
- TeamchangeFrags(client); // move the players frags
- SetPlayerColors(client, team_colour - 1); // set the players colour
- Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, client.origin, '0 0 0'); // kill the player
-
- lockteams = lockteams_backup; // restore the team lock
-
- LogTeamchange(client.playerid, client.team, type);
-}
void CopyBody_Think();
void CopyBody(float keepvelocity);
-float player_getspecies();
-
void player_setupanimsformodel();
-void player_anim ();
+void player_anim();
-void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
+void PlayerCorpseDamage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
// g_<gametype>_str:
// If 0, default is used.
// For consistency, negative values there are mapped to zero too.
#define GAMETYPE_DEFAULTED_SETTING(str) \
((gametype_setting_tmp = cvar(strcat("g_", GetGametype(), "_" #str))), \
- (gametype_setting_tmp < 0) ? 0 : \
- (gametype_setting_tmp == 0 || autocvar_g_respawn_delay_forced) ? max(0, autocvar_g_##str) : \
- gametype_setting_tmp)
-
+ (gametype_setting_tmp < 0) ? 0 \
+ : (gametype_setting_tmp == 0 || autocvar_g_respawn_delay_forced) ? max(0, autocvar_g_##str) \
+ : gametype_setting_tmp)
void calculate_player_respawn_time();
void ClientKill_Now_TeamChange();
-void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
-
-.float muted; // to be used by prvm_edictset server playernumber muted 1
-float Say(entity source, float teamsay, entity privatesay, string msgin, float floodcontrol);
-// message "": do not say, just test flood control
-// return value:
-// 1 = accept
-// 0 = reject
-// -1 = fake accept
-
-float GetVoiceMessageVoiceType(string type);
-
-string allvoicesamples;
-.string GetVoiceMessageSampleField(string type);
-
-.string GetPlayerSoundSampleField(string type);
-
-void PrecacheGlobalSound(string samplestring);
-
-void PrecachePlayerSounds(string f);
-
-void ClearPlayerSounds();
-
-float LoadPlayerSounds(string f, float first);
-
-.int modelindex_for_playersound;
-.int skin_for_playersound;
-void UpdatePlayerSounds();
-
-void FakeGlobalSound(string sample, float chan, float voicetype);
-
-void GlobalSound(string sample, float chan, float voicetype);
+void MoveToTeam(entity client, float team_colour, float type);
-void PlayerSound(.string samplefield, float chan, float voicetype);
+void PlayerDamage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
-void VoiceMessage(string type, string msg);
+/** to be used by `prvm_edictset server playernumber muted 1` */
+.float muted;
+int Say(entity source, float teamsay, entity privatesay, string msgin, float floodcontrol);
-void MoveToTeam(entity client, float team_colour, float type);
#endif
{
if (argv(1) != "")
{
- if (argc >= 3) VoiceMessage(argv(1), substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2)));
- else VoiceMessage(argv(1), "");
+ entity e = GetVoiceMessage(argv(1));
+ if (!e)
+ {
+ sprint(this, sprintf("Invalid voice. Use one of: %s\n", allvoicesamples));
+ return;
+ }
+ if (argc >= 3) VoiceMessage(e, substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2)));
+ else VoiceMessage(e, "");
return;
}
// =======================
// Resets the state of all clients, items, weapons, waypoints, ... of the map.
-void reset_map(float dorespawn)
+void reset_map(bool dorespawn)
{
SELFPARAM();
MUTATOR_CALLHOOK(reset_map_global);
- for (entity e = world; (e = nextent(e)); )
- {
- setself(e);
- if (IS_NOT_A_CLIENT(self))
+ FOREACH_ENTITY_ORDERED(IS_NOT_A_CLIENT(it), LAMBDA(
+ if (it.reset)
{
- if (self.reset)
- {
- self.reset();
- continue;
- }
-
- if (self.team_saved) self.team = self.team_saved;
-
- if (self.flags & FL_PROJECTILE) // remove any projectiles left
- remove(self);
+ WITH(entity, self, it, it.reset(it));
+ continue;
}
- }
+ if (it.team_saved) it.team = it.team_saved;
+ if (it.flags & FL_PROJECTILE) remove(it); // remove any projectiles left
+ ));
// Waypoints and assault start come LAST
- for (entity e = world; (e = nextent(e)); )
- {
- setself(e);
- if (IS_NOT_A_CLIENT(self))
- {
- if (self.reset2)
- {
- self.reset2();
- continue;
- }
- }
- }
+ FOREACH_ENTITY_ORDERED(IS_NOT_A_CLIENT(it), LAMBDA(
+ if (it.reset2) WITH(entity, self, it, it.reset2());
+ ));
entity e;
FOR_EACH_PLAYER(e)
- if (e.frozen) WITH(entity, self, e, Unfreeze(self));
+ if (e.frozen) WITH(entity, self, e, Unfreeze(e));
// Moving the player reset code here since the player-reset depends
// on spawnpoint entities which have to be reset first --blub
void ReadyRestart_think()
{
SELFPARAM();
- restart_mapalreadyrestarted = 1;
+ restart_mapalreadyrestarted = true;
reset_map(true);
Score_ClearAll();
- remove(self);
+ remove(this);
}
// Forces a restart of the game without actually reloading the map // this is a mess...
void ReadyRestart_force()
{
- entity tmp_player, restart_timer;
-
bprint("^1Server is restarting...\n");
VoteReset();
// clear overtime, we have to decrease timelimit to its original value again.
- if (checkrules_overtimesadded > 0 && g_race_qualifying != 2) cvar_set("timelimit", ftos(autocvar_timelimit - (checkrules_overtimesadded * autocvar_timelimit_overtime)));
+ if (checkrules_overtimesadded > 0 && g_race_qualifying != 2)
+ cvar_set("timelimit", ftos(autocvar_timelimit - (checkrules_overtimesadded * autocvar_timelimit_overtime)));
checkrules_suddendeathend = checkrules_overtimesadded = checkrules_suddendeathwarning = 0;
- readyrestart_happened = 1;
+ readyrestart_happened = true;
game_starttime = time + RESTART_COUNTDOWN;
+ entity tmp_player;
+
// clear player attributes
FOR_EACH_CLIENT(tmp_player)
{
PS_GR_P_ADDVAL(tmp_player, PLAYERSTATS_ALIVETIME, -PS_GR_P_ADDVAL(tmp_player, PLAYERSTATS_ALIVETIME, 0));
}
- restart_mapalreadyrestarted = 0; // reset this var, needed when cvar sv_ready_restart_repeatable is in use
+ restart_mapalreadyrestarted = false; // reset this var, needed when cvar sv_ready_restart_repeatable is in use
// disable the warmup global for the server
warmup_stage = 0; // once the game is restarted the game is in match stage
// reset the .ready status of all players (also spectators)
FOR_EACH_REALCLIENT(tmp_player)
{
- tmp_player.ready = 0;
+ tmp_player.ready = false;
}
readycount = 0;
Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
// lock teams with lockonrestart
if (autocvar_teamplay_lockonrestart && teamplay)
{
- lockteams = 1;
+ lockteams = true;
bprint("^1The teams are now locked.\n");
}
// initiate the restart-countdown-announcer entity
if (autocvar_sv_ready_restart_after_countdown)
{
- restart_timer = spawn();
+ entity restart_timer = new(restart_timer);
+ make_pure(restart_timer);
restart_timer.think = ReadyRestart_think;
restart_timer.nextthink = game_starttime;
}
{
tmp_player.allowed_timeouts = autocvar_sv_timeout_number;
}
- // reset map immediately if this cvar is not set
- if (!autocvar_sv_ready_restart_after_countdown) reset_map(true); }
- if (autocvar_sv_eventlog) GameLogEcho(":restart"); }
+ }
+ // reset map immediately if this cvar is not set
+ if (!autocvar_sv_ready_restart_after_countdown) reset_map(true);
+ if (autocvar_sv_eventlog) GameLogEcho(":restart");
+}
void ReadyRestart()
{
// Reset ALL scores, but only do that at the beginning of the countdown if sv_ready_restart_after_countdown is off!
// Otherwise scores could be manipulated during the countdown.
- if (!autocvar_sv_ready_restart_after_countdown) Score_ClearAll();
+ if (!autocvar_sv_ready_restart_after_countdown) Score_ClearAll();
ReadyRestart_force();
}
const int FL_SPAWNING = BIT(18);
const int FL_PICKUPITEMS = BIT(19);
-const int SVC_SOUND = 6;
-const int SVC_STOPSOUND = 16;
const int SVC_SETVIEW = 5;
const int RESPAWN_FORCE = 1;
float team1_score, team2_score, team3_score, team4_score;
-float maxclients;
-
// flag set on worldspawn so that the code knows if it is dedicated or not
float server_is_dedicated;
float next_pingtime;
-// player sounds, voice messages
-// TODO implemented fall and falling
-#define ALLPLAYERSOUNDS \
- _VOICEMSG(death) \
- _VOICEMSG(drown) \
- _VOICEMSG(fall) \
- _VOICEMSG(falling) \
- _VOICEMSG(gasp) \
- _VOICEMSG(jump) \
- _VOICEMSG(pain100) \
- _VOICEMSG(pain25) \
- _VOICEMSG(pain50) \
- _VOICEMSG(pain75)
-
-#define ALLVOICEMSGS \
- _VOICEMSG(attack) \
- _VOICEMSG(attackinfive) \
- _VOICEMSG(coverme) \
- _VOICEMSG(defend) \
- _VOICEMSG(freelance) \
- _VOICEMSG(incoming) \
- _VOICEMSG(meet) \
- _VOICEMSG(needhelp) \
- _VOICEMSG(seenflag) \
- _VOICEMSG(taunt) \
- _VOICEMSG(teamshoot)
-
-#define _VOICEMSG(m) .string playersound_##m;
-ALLPLAYERSOUNDS
-ALLVOICEMSGS
-#undef _VOICEMSG
-
-// reserved sound names for the future (some models lack sounds for them):
-// _VOICEMSG(flagcarriertakingdamage) \
-// _VOICEMSG(getflag) \
-// reserved sound names for the future (ALL models lack sounds for them):
-// _VOICEMSG(affirmative) \
-// _VOICEMSG(attacking) \
-// _VOICEMSG(defending) \
-// _VOICEMSG(roaming) \
-// _VOICEMSG(onmyway) \
-// _VOICEMSG(droppedflag) \
-// _VOICEMSG(negative) \
-// _VOICEMSG(seenenemy) \
-// /**/
-
-string globalsound_fall;
-string globalsound_metalfall;
-string globalsound_step;
-string globalsound_metalstep;
-
-const float VOICETYPE_PLAYERSOUND = 10;
-const float VOICETYPE_TEAMRADIO = 11;
-const float VOICETYPE_LASTATTACKER = 12;
-const float VOICETYPE_LASTATTACKER_ONLY = 13;
-const float VOICETYPE_AUTOTAUNT = 14;
-const float VOICETYPE_TAUNT = 15;
-
-void PrecachePlayerSounds(string f);
-void PrecacheGlobalSound(string samplestring);
-void UpdatePlayerSounds();
-void ClearPlayerSounds();
-void PlayerSound(.string samplefield, float channel, float voicetype);
-void GlobalSound(string samplestring, float channel, float voicetype);
-void FakeGlobalSound(string samplestring, float channel, float voicetype);
-void VoiceMessage(string type, string message);
-float GetPlayerSoundSampleField_notFound;
-.string GetVoiceMessageSampleField(string type);
-
// autotaunt system
.float cvar_cl_autotaunt;
.float cvar_cl_voice_directional;
void SUB_DontUseTargets();
void SUB_UseTargets();
-.void() reset; // if set, an entity is reset using this
+.void(entity this) reset; // if set, an entity is reset using this
.void() reset2; // if set, an entity is reset using this (after calling ALL the reset functions for other entities)
void ClientData_Touch(entity e);
+++ /dev/null
-#include "ent_cs.qh"
-
-float entcs_customize()
-{
- SELFPARAM();
- entity o = self.owner;
- if(o.deadflag != DEAD_NO)
- return false;
- if (!IS_PLAYER(o))
- return false;
- if(other == o)
- return false;
- if((IS_PLAYER(other)) || other.caplayer)
- if(!teamplay || o.team != other.team)
- if (!radar_showennemies)
- return false;
- return true;
-}
-
-bool entcs_send(entity this, entity to, int sf)
-{
- WriteHeader(MSG_ENTITY, ENT_CLIENT_ENTCS);
- WriteByte(MSG_ENTITY, sf);
- if(sf & BIT(0))
- WriteByte(MSG_ENTITY, num_for_edict(self.owner) - 1);
- if(sf & BIT(1))
- {
- WriteShort(MSG_ENTITY, self.origin.x);
- WriteShort(MSG_ENTITY, self.origin.y);
- WriteShort(MSG_ENTITY, self.origin.z);
- }
- if(sf & BIT(2))
- WriteByte(MSG_ENTITY, self.angles.y * 256.0 / 360);
- if(sf & BIT(3))
- WriteByte(MSG_ENTITY, self.health / 10); // FIXME use a better scale?
- if(sf & BIT(4))
- WriteByte(MSG_ENTITY, self.armorvalue / 10); // FIXME use a better scale?
- return true;
-}
-
-void entcs_think()
-{
- SELFPARAM();
- self.nextthink = time + 0.033333333333; // increase this to like 0.15 once the client can do smoothing
- entity o = self.owner;
- if (o.origin != self.origin)
- {
- setorigin(self, o.origin);
- self.SendFlags |= BIT(1);
- }
- if (o.angles.y != self.angles.y)
- {
- self.angles = o.angles;
- self.SendFlags |= BIT(2);
- }
- if (o.health != self.health)
- {
- self.health = o.health;
- self.SendFlags |= BIT(3);
- }
- if (o.armorvalue != self.armorvalue)
- {
- self.armorvalue = o.armorvalue;
- self.SendFlags |= BIT(4);
- }
-}
-
-entity attach_entcs(entity e)
-{
- entity ent = e.entcs = new(entcs_sender);
- make_pure(ent);
- ent.owner = e;
- ent.think = entcs_think;
- ent.nextthink = time;
-
- Net_LinkEntity(ent, false, 0, entcs_send);
- ent.customizeentityforclient = entcs_customize;
-
- return ent;
-}
-
-void detach_entcs(entity e)
-{
- if (!e.entcs) return;
- remove(e.entcs);
- e.entcs = NULL;
-}
+++ /dev/null
-#ifndef ENT_CS_H
-#define ENT_CS_H
-
-/**
- * The point of these entities is to avoid the problems
- * with clientprediction.
- * If you add SendEntity to players, the engine will not
- * do any prediction anymore, and you'd have to write the whole
- * prediction code in CSQC, you want that? :P
- * Data can depend on gamemode. For now, it serves as GPS entities
- * in onslaught... YAY ;)
- */
-
-.entity entcs;
-
-float entcs_customize();
-
-bool entcs_send(entity this, entity to, int sf);
-
-void entcs_think();
-
-entity attach_entcs(entity e);
-
-void detach_entcs(entity e);
-
-#endif
#include "weapons/accuracy.qh"
#include "weapons/csqcprojectile.qh"
#include "weapons/selection.qh"
-#include "../common/buffs/all.qh"
#include "../common/constants.qh"
#include "../common/deathtypes/all.qh"
#include "../common/notifications.qh"
{
// after a frag, exchange the current weapon (or the culprit, if detectable) by a new random weapon
Weapon culprit = DEATH_WEAPONOF(deathtype);
- if(!culprit)
- culprit = get_weaponinfo(attacker.weapon);
- else if(!(attacker.weapons & WepSet_FromWeapon(culprit.m_id)))
- culprit = get_weaponinfo(attacker.weapon);
+ if(!culprit) culprit = get_weaponinfo(attacker.weapon);
+ else if(!(attacker.weapons & (culprit.m_wepset))) culprit = get_weaponinfo(attacker.weapon);
if(g_weaponarena_random_with_blaster && culprit == WEP_BLASTER) // WEAPONTODO: Shouldn't this be in a mutator?
{
// all others (including the culprit): remove
GiveFrags_randomweapons.weapons &= ~attacker.weapons;
- GiveFrags_randomweapons.weapons &= ~WepSet_FromWeapon(culprit.m_id);
+ GiveFrags_randomweapons.weapons &= ~(culprit.m_wepset);
// among the remaining ones, choose one by random
W_RandomWeapons(GiveFrags_randomweapons, 1);
if(GiveFrags_randomweapons.weapons)
{
attacker.weapons |= GiveFrags_randomweapons.weapons;
- attacker.weapons &= ~WepSet_FromWeapon(culprit.m_id);
+ attacker.weapons &= ~(culprit.m_wepset);
}
}
return false;
}
+.int buffs = _STAT(BUFFS); // TODO: remove
+
void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
{
// Sanity check
farcent.origin = hitloc;
farcent.forcetype = FORCETYPE_FORCEATPOS;
farcent.nextthink = time + 0.1;
- farcent.think = SUB_Remove;
+ farcent.think = SUB_Remove_self;
}
else
{
//pl.disableclientprediction = false;
}
-void GrapplingHookReset()
-{SELFPARAM();
- if(self.realowner.hook == self)
- RemoveGrapplingHook(self.owner);
+void GrapplingHookReset(entity this)
+{
+ if(this.realowner.hook == this)
+ RemoveGrapplingHook(this.owner);
else // in any case:
- remove(self);
+ remove(this);
}
void GrapplingHookThink();
void() SUB_CalcMoveDone;
void() SUB_CalcAngleMoveDone;
//void() SUB_UseTargets;
-void() SUB_Remove;
spawnfunc(info_null);
void updateanim(entity e);
-/*
-==================
-SUB_Remove
-Remove self
-==================
-*/
-void SUB_Remove ();
/*
==================
#include "scores.qh"
#include "teamplay.qh"
#include "weapons/weaponstats.qh"
-#include "../common/buffs/all.qh"
#include "../common/constants.qh"
#include "../common/deathtypes/all.qh"
#include "../common/mapinfo.qh"
compressShortVector_init();
- entity head;
- head = nextent(world);
maxclients = 0;
- while(head)
+ for (entity head = nextent(world); head; head = nextent(head))
{
++maxclients;
- head = nextent(head);
}
server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? true : false);
void FixIntermissionClient(entity e)
{
- string s;
if(!e.autoscreenshot) // initial call
{
e.autoscreenshot = time + 0.8; // used for autoscreenshot
if(IS_REAL_CLIENT(e))
{
stuffcmd(e, "\nscr_printspeed 1000000\n");
- s = autocvar_sv_intermission_cdtrack;
- if(s != "")
- stuffcmd(e, strcat("\ncd loop ", s, "\n"));
+ string list = autocvar_sv_intermission_cdtrack;
+ for(string it; (it = car(list)); list = cdr(list))
+ RandomSelection_Add(world, 0, it, 1, 1);
+ if(RandomSelection_chosen_string && RandomSelection_chosen_string != "")
+ stuffcmd(e, strcat("\ncd loop ", RandomSelection_chosen_string, "\n"));
msg_entity = e;
WriteByte(MSG_ONE, SVC_INTERMISSION);
}
{
e = get_weaponinfo(j);
if (!(e.spawnflags & WEP_FLAG_MUTATORBLOCKED))
- g_weaponarena_weapons |= WepSet_FromWeapon(j);
+ g_weaponarena_weapons |= (e.m_wepset);
}
}
else if (s == "most")
e = get_weaponinfo(j);
if (!(e.spawnflags & WEP_FLAG_MUTATORBLOCKED))
if (e.spawnflags & WEP_FLAG_NORMAL)
- g_weaponarena_weapons |= WepSet_FromWeapon(j);
+ g_weaponarena_weapons |= (e.m_wepset);
}
}
else if (s == "none")
e = get_weaponinfo(j);
if (e.netname == s)
{
- g_weaponarena_weapons |= WepSet_FromWeapon(j);
+ g_weaponarena_weapons |= (e.m_wepset);
g_weaponarena_list = strcat(g_weaponarena_list, e.m_name, " & ");
break;
}
{
e = get_weaponinfo(i);
int w = want_weapon(e, false);
+ WepSet s = e.m_wepset;
if(w & 1)
- start_weapons |= WepSet_FromWeapon(i);
+ start_weapons |= s;
if(w & 2)
- start_weapons_default |= WepSet_FromWeapon(i);
+ start_weapons_default |= s;
if(w & 4)
- start_weapons_defaultmask |= WepSet_FromWeapon(i);
+ start_weapons_defaultmask |= s;
}
}
{
e = get_weaponinfo(i);
int w = want_weapon(e, g_warmup_allguns);
+ WepSet s = (e.m_wepset);
if(w & 1)
- warmup_start_weapons |= WepSet_FromWeapon(i);
+ warmup_start_weapons |= s;
if(w & 2)
- warmup_start_weapons_default |= WepSet_FromWeapon(i);
+ warmup_start_weapons_default |= s;
if(w & 4)
- warmup_start_weapons_defaultmask |= WepSet_FromWeapon(i);
+ warmup_start_weapons_defaultmask |= s;
}
}
}
for (i = WEP_FIRST; i <= WEP_LAST; ++i)
{
e = get_weaponinfo(i);
- if(precache_weapons & WepSet_FromWeapon(i)) {
- Weapon w = get_weaponinfo(i);
- w.wr_init(w);
+ if(precache_weapons & (e.m_wepset)) {
+ e.wr_init(e);
}
}
warmup_start_ammo_fuel = max(0, warmup_start_ammo_fuel);
}
-float sound_allowed(float destin, entity e)
-{
- // sounds from world may always pass
- for (;;)
- {
- if (e.classname == "body")
- e = e.enemy;
- else if (e.realowner && e.realowner != e)
- e = e.realowner;
- else if (e.owner && e.owner != e)
- e = e.owner;
- else
- break;
- }
- // sounds to self may always pass
- if (destin == MSG_ONE)
- if (e == msg_entity)
- return true;
- // sounds by players can be removed
- if (autocvar_bot_sound_monopoly)
- if (IS_REAL_CLIENT(e))
- return false;
- // anything else may pass
- return true;
-}
-
-void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float attenu)
-{
- float entno, idx;
-
- if (!sound_allowed(_dest, e))
- return;
-
- entno = num_for_edict(e);
- idx = precache_sound_index(samp);
-
- int sflags;
- sflags = 0;
-
- attenu = floor(attenu * 64);
- vol = floor(vol * 255);
-
- if (vol != 255)
- sflags |= SND_VOLUME;
- if (attenu != 64)
- sflags |= SND_ATTENUATION;
- if (entno >= 8192 || chan < 0 || chan > 7)
- sflags |= SND_LARGEENTITY;
- if (idx >= 256)
- sflags |= SND_LARGESOUND;
-
- WriteByte(_dest, SVC_SOUND);
- WriteByte(_dest, sflags);
- if (sflags & SND_VOLUME)
- WriteByte(_dest, vol);
- if (sflags & SND_ATTENUATION)
- WriteByte(_dest, attenu);
- if (sflags & SND_LARGEENTITY)
- {
- WriteShort(_dest, entno);
- WriteByte(_dest, chan);
- }
- else
- {
- WriteShort(_dest, entno * 8 + chan);
- }
- if (sflags & SND_LARGESOUND)
- WriteShort(_dest, idx);
- else
- WriteByte(_dest, idx);
-
- WriteCoord(_dest, o.x);
- WriteCoord(_dest, o.y);
- WriteCoord(_dest, o.z);
-}
-void soundto(float _dest, entity e, float chan, string samp, float vol, float _atten)
-{
- vector o;
-
- if (!sound_allowed(_dest, e))
- return;
-
- o = e.origin + 0.5 * (e.mins + e.maxs);
- soundtoat(_dest, e, o, chan, samp, vol, _atten);
-}
-void soundat(entity e, vector o, float chan, string samp, float vol, float _atten)
-{
- soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, _atten);
-}
-void stopsoundto(float _dest, entity e, float chan)
-{
- float entno;
-
- if (!sound_allowed(_dest, e))
- return;
-
- entno = num_for_edict(e);
-
- if (entno >= 8192 || chan < 0 || chan > 7)
- {
- float idx, sflags;
- idx = precache_sound_index(SND(Null));
- sflags = SND_LARGEENTITY;
- if (idx >= 256)
- sflags |= SND_LARGESOUND;
- WriteByte(_dest, SVC_SOUND);
- WriteByte(_dest, sflags);
- WriteShort(_dest, entno);
- WriteByte(_dest, chan);
- if (sflags & SND_LARGESOUND)
- WriteShort(_dest, idx);
- else
- WriteByte(_dest, idx);
- WriteCoord(_dest, e.origin.x);
- WriteCoord(_dest, e.origin.y);
- WriteCoord(_dest, e.origin.z);
- }
- else
- {
- WriteByte(_dest, SVC_STOPSOUND);
- WriteShort(_dest, entno * 8 + chan);
- }
-}
-void stopsound(entity e, float chan)
-{
- if (!sound_allowed(MSG_BROADCAST, e))
- return;
-
- stopsoundto(MSG_BROADCAST, e, chan); // unreliable, gets there fast
- stopsoundto(MSG_ALL, e, chan); // in case of packet loss
-}
-
-void play2(entity e, string filename)
-{
- //stuffcmd(e, strcat("play2 ", filename, "\n"));
- msg_entity = e;
- soundtoat(MSG_ONE, world, '0 0 0', CH_INFO, filename, VOL_BASE, ATTEN_NONE);
-}
-
-// use this one if you might be causing spam (e.g. from touch functions that might get called more than once per frame)
-.float spamtime;
-float spamsound(entity e, float chan, string samp, float vol, float _atten)
-{
- if (!sound_allowed(MSG_BROADCAST, e))
- return false;
-
- if (time > e.spamtime)
- {
- e.spamtime = time;
- _sound(e, chan, samp, vol, _atten);
- return true;
- }
- return false;
-}
-
-void play2team(float t, string filename)
-{
- entity head;
-
- if (autocvar_bot_sound_monopoly)
- return;
-
- FOR_EACH_REALPLAYER(head)
- {
- if (head.team == t)
- play2(head, filename);
- }
-}
-
-void play2all(string samp)
-{
- if (autocvar_bot_sound_monopoly)
- return;
-
- _sound(world, CH_INFO, samp, VOL_BASE, ATTEN_NONE);
-}
-
-void PrecachePlayerSounds(string f);
void precache_playermodel(string m)
{
float globhandle, i, n;
precache_playermodels(autocvar_sv_defaultplayermodel);
}
- if (g_footsteps)
- {
- PrecacheGlobalSound((globalsound_step = "misc/footstep0 6"));
- PrecacheGlobalSound((globalsound_metalstep = "misc/metalfootstep0 6"));
- }
-
- // gore and miscellaneous sounds
- PrecacheGlobalSound((globalsound_fall = "misc/hitground 4"));
- PrecacheGlobalSound((globalsound_metalfall = "misc/metalhitground 4"));
-
#if 0
// Disabled this code because it simply does not work (e.g. ignores bgmvolume, overlaps with "cd loop" controlled tracks).
if(s != "")
{
db_put(ServerProgsDB, strcat("/uid2name/", myuid), s);
- db_put(ServerProgsDB, strcat("uid2name", myuid), "");
+ db_remove(ServerProgsDB, strcat("uid2name", myuid));
}
}
void objerror(string s);
void droptofloor();
-void() SUB_Remove;
void attach_sameorigin(entity e, entity to, string tag);
#define PROJECTILE_TOUCH if(WarpZone_Projectile_Touch()) return
-const string STR_PLAYER = "player";
-const string STR_SPECTATOR = "spectator";
-const string STR_OBSERVER = "observer";
-
-#define IS_PLAYER(v) ((v).classname == STR_PLAYER)
-#define IS_SPEC(v) ((v).classname == STR_SPECTATOR)
-#define IS_OBSERVER(v) ((v).classname == STR_OBSERVER)
-#define IS_CLIENT(v) (v.flags & FL_CLIENT)
-#define IS_BOT_CLIENT(v) (clienttype(v) == CLIENTTYPE_BOT)
-#define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL)
-#define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT)
-
-#define IS_MONSTER(v) (v.flags & FL_MONSTER)
-#define IS_VEHICLE(v) (v.vehicle_flags & VHF_ISVEHICLE)
-#define IS_TURRET(v) (v.turret_flags & TUR_FLAG_ISTURRET)
-
-#define FOR_EACH_CLIENTSLOT(v) for(v = world; (v = nextent(v)) && (num_for_edict(v) <= maxclients); )
-#define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if(IS_CLIENT(v))
-#define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(IS_REAL_CLIENT(v))
-
-#define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if(IS_PLAYER(v))
-#define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if (!IS_PLAYER(v)) // Samual: shouldn't this be IS_SPEC(v)? and rather create a separate macro to include observers too
-#define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if(IS_PLAYER(v))
-
-#define FOR_EACH_MONSTER(v) for(v = world; (v = findflags(v, flags, FL_MONSTER)) != world; )
-
#define CENTER_OR_VIEWOFS(ent) (ent.origin + (IS_PLAYER(ent) ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5)))
// copies a string to a tempstring (so one can strunzone it)
//#NO AUTOCVARS END
-
-// Sound functions
-//string precache_sound (string s) = #19;
-// hack
-float precache_sound_index (string s) = #19;
-
-const float SND_VOLUME = BIT(0);
-const float SND_ATTENUATION = BIT(1);
-const float SND_LARGEENTITY = BIT(3);
-const float SND_LARGESOUND = BIT(4);
-
const float INITPRIO_FIRST = 0;
const float INITPRIO_GAMETYPE = 0;
const float INITPRIO_GAMETYPE_FALLBACK = 1;
#include "../../common/stats.qh"
#include "../../common/teams.qh"
#include "../../common/util.qh"
- #include "../../common/nades/all.qh"
- #include "../../common/buffs/all.qh"
#include "../../common/command/markup.qh"
#include "../../common/command/rpn.qh"
#include "../../common/command/generic.qh"
#define EV_SpectateSet(i, o) \
/**/ i(entity, __self) \
/**/ i(entity, spec_player) \
+ /**/ o(entity, spec_player) \
/**/
entity spec_player;
MUTATOR_HOOKABLE(SpectateSet, EV_SpectateSet);
#define EV_SpectateNext(i, o) \
/**/ i(entity, __self) \
/**/ i(entity, spec_player) \
+ /**/ o(entity, spec_player) \
/**/
MUTATOR_HOOKABLE(SpectateNext, EV_SpectateNext);
#define EV_SpectatePrev(i, o) \
/**/ i(entity, __self) \
/**/ i(entity, spec_player) \
+ /**/ o(entity, spec_player) \
/**/ i(entity, spec_first) \
/**/
entity spec_first;
// reset this objective. Used when spawning an objective
// and when a new round starts
-void assault_objective_reset()
-{SELFPARAM();
- self.health = ASSAULT_VALUE_INACTIVE;
+void assault_objective_reset(entity this)
+{
+ this.health = ASSAULT_VALUE_INACTIVE;
}
// decrease the health of targeted objectives
assault_setenemytoobjective();
}
-void target_assault_roundend_reset()
-{SELFPARAM();
+void target_assault_roundend_reset(entity this)
+{
//print("round end reset\n");
- self.cnt = self.cnt + 1; // up round counter
- self.winning = 0; // up round
+ ++this.cnt; // up round counter
+ this.winning = false; // up round
}
void target_assault_roundend_use()
else
assault_attacker_team = NUM_TEAM_1;
- entity ent;
- for(ent = world; (ent = nextent(ent)); )
- {
- if(clienttype(ent) == CLIENTTYPE_NOTACLIENT)
- {
- if(ent.team_saved == NUM_TEAM_1)
- ent.team_saved = NUM_TEAM_2;
- else if(ent.team_saved == NUM_TEAM_2)
- ent.team_saved = NUM_TEAM_1;
- }
- }
+ FOREACH_ENTITY(clienttype(it) == CLIENTTYPE_NOTACLIENT, LAMBDA(
+ if (it.team_saved == NUM_TEAM_1) it.team_saved = NUM_TEAM_2;
+ else if (it.team_saved == NUM_TEAM_2) it.team_saved = NUM_TEAM_1;
+ ));
// reset the level with a countdown
cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60));
spawnfunc(target_objective)
{
- if (!g_assault) { remove(self); return; }
+ if (!g_assault) { remove(this); return; }
- self.classname = "target_objective";
- self.use = assault_objective_use;
- assault_objective_reset();
- self.reset = assault_objective_reset;
- self.spawn_evalfunc = target_objective_spawn_evalfunc;
+ this.classname = "target_objective";
+ this.use = assault_objective_use;
+ this.reset = assault_objective_reset;
+ this.reset(this);
+ this.spawn_evalfunc = target_objective_spawn_evalfunc;
}
spawnfunc(target_objective_decrease)
return false;
}
-// Returns next available player to spectate if g_ca_spectate_enemies == 0
+/** Returns next available player to spectate if g_ca_spectate_enemies == 0 */
entity CA_SpectateNext(entity player, entity start)
{
- if(SAME_TEAM(start, player))
- return start;
-
- entity spec_other = start;
+ if (SAME_TEAM(start, player)) return start;
// continue from current player
- while(spec_other && DIFF_TEAM(spec_other, player))
- spec_other = find(spec_other, classname, "player");
-
- if (!spec_other)
+ for (entity e = start; (e = find(e, classname, "player")); )
{
- // restart from begining
- spec_other = find(spec_other, classname, "player");
- while(spec_other && DIFF_TEAM(spec_other, player))
- spec_other = find(spec_other, classname, "player");
+ if (SAME_TEAM(player, e)) return e;
}
-
- return spec_other;
+ // restart from begining
+ for (entity e = NULL; (e = find(e, classname, "player")); )
+ {
+ if (SAME_TEAM(player, e)) return e;
+ }
+ return start;
}
+
MUTATOR_HOOKFUNCTION(ca, PlayerSpawn)
{SELFPARAM();
self.caplayer = 1;
bool autocvar_g_ctf_flag_glowtrails;
int autocvar_g_ctf_flag_health;
bool autocvar_g_ctf_flag_return;
+bool autocvar_g_ctf_flag_return_carrying;
float autocvar_g_ctf_flag_return_carried_radius;
float autocvar_g_ctf_flag_return_time;
bool autocvar_g_ctf_flag_return_when_unreachable;
case FLAG_DROPPED:
{
- if(CTF_SAMETEAM(toucher, flag) && (autocvar_g_ctf_flag_return || num_perteam <= 1) && flag.team) // automatically return if there's only 1 player on the team
+ if(CTF_SAMETEAM(toucher, flag) && (autocvar_g_ctf_flag_return || num_perteam <= 1 || (autocvar_g_ctf_flag_return_carrying && toucher.flagcarried)) && flag.team) // automatically return if there's only 1 player on the team
ctf_Handle_Return(flag, toucher); // toucher just returned his own flag
else if(is_not_monster && (!toucher.flagcarried) && ((toucher != flag.ctf_dropper) || (time > flag.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
ctf_Handle_Pickup(flag, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
ctf_CheckStalemate();
}
-void ctf_Reset()
-{SELFPARAM();
- if(self.owner)
- if(IS_PLAYER(self.owner))
- ctf_Handle_Throw(self.owner, world, DROP_RESET);
+void ctf_Reset(entity this)
+{
+ if(this.owner && IS_PLAYER(this.owner))
+ ctf_Handle_Throw(this.owner, world, DROP_RESET);
- ctf_RespawnFlag(self);
+ ctf_RespawnFlag(this);
}
void ctf_DelayedFlagSetup() // called after a flag is placed on a map by ctf_FlagSetup()
MUTATOR_HOOKFUNCTION(cts, Race_FinalCheckpoint)
{
if(autocvar_g_cts_finish_kill_delay)
- CTS_ClientKill(self);
+ CTS_ClientKill(race_player);
return false;
}
dompoint_captured();
}
-void dom_controlpoint_setup()
-{SELFPARAM();
+void dom_controlpoint_setup(entity this);
+void dom_controlpoint_setup_self() { SELFPARAM(); dom_controlpoint_setup(this); }
+void dom_controlpoint_setup(entity this)
+{
entity head;
// find the spawnfunc_dom_team representing unclaimed points
head = find(world, classname, "dom_team");
remove(self);
return;
}
- self.think = dom_controlpoint_setup;
+ self.think = dom_controlpoint_setup_self;
self.nextthink = time + 0.1;
self.reset = dom_controlpoint_setup;
setself(this);
}
-void _spawnfunc_dom_controlpoint() { SELFPARAM(); spawnfunc_dom_controlpoint(self); }
+void self_spawnfunc_dom_controlpoint() { SELFPARAM(); spawnfunc_dom_controlpoint(self); }
void dom_spawnpoint(vector org)
{SELFPARAM();
setself(spawn());
self.classname = "dom_controlpoint";
- self.think = _spawnfunc_dom_controlpoint;
+ self.think = self_spawnfunc_dom_controlpoint;
self.nextthink = time;
setorigin(self, org);
spawnfunc_dom_controlpoint(this);
monster = spawnmonster("", mon, world, world, e.origin, false, false, 2);
else return;
- e.think = SUB_Remove;
+ e.think = SUB_Remove_self;
e.nextthink = time + 0.1;
}
else
WaypointSprite_Kill(plyr.waypointsprite_attachedforcarrier);
}
-void ka_Reset() // used to clear the ballcarrier whenever the match switches from warmup to normal
-{SELFPARAM();
- if((self.owner) && (IS_PLAYER(self.owner)))
- ka_DropEvent(self.owner);
+/** used to clear the ballcarrier whenever the match switches from warmup to normal */
+void ka_Reset(entity this)
+{
+ if((this.owner) && (IS_PLAYER(this.owner)))
+ ka_DropEvent(this.owner);
if(time < game_starttime)
{
- self.think = ka_RespawnBall;
- self.touch = func_null;
- self.nextthink = game_starttime;
+ this.think = ka_RespawnBall;
+ this.touch = func_null;
+ this.nextthink = game_starttime;
}
else
ka_RespawnBall();
self.nextthink = time + 0.05;
}
-void key_reset()
-{SELFPARAM();
- kh_Key_AssignTo(self, world);
- kh_Key_Remove(self);
+void key_reset(entity this)
+{
+ kh_Key_AssignTo(this, world);
+ kh_Key_Remove(this);
}
const string STR_ITEM_KH_KEY = "item_kh_key";
}
else
{
- float missing_teams_mask = (!!p1) + (!!p2) * 2;
- if(kh_teams >= 3) missing_teams_mask += (!!p3) * 4;
- if(kh_teams >= 4) missing_teams_mask += (!!p4) * 8;
+ float missing_teams_mask = boolean(p1) + boolean(p2) * 2;
+ if(kh_teams >= 3) missing_teams_mask += boolean(p3) * 4;
+ if(kh_teams >= 4) missing_teams_mask += boolean(p4) * 8;
if(prev_missing_teams_mask != missing_teams_mask)
{
Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
MUTATOR_HOOKFUNCTION(lms, FilterItem)
{SELFPARAM();
if(autocvar_g_lms_extra_lives)
- if(self.itemdef == ITEM_HealthMega)
- {
- self.max_health = 1;
+ if(self.itemdef == ITEM_ExtraLife)
return false;
- }
+
+ return true;
+}
+
+void lms_extralife()
+{SELFPARAM();
+ StartItem(this, ITEM_ExtraLife);
+}
+
+MUTATOR_HOOKFUNCTION(lms, OnEntityPreSpawn)
+{SELFPARAM();
+ if (!autocvar_g_powerups) return false;
+ if (!autocvar_g_lms_extra_lives) return false;
+
+ // Can't use .itemdef here
+ if (self.classname != "item_health_mega") return false;
+
+ entity e = spawn();
+ e.think = lms_extralife;
+
+ e.nextthink = time + 0.1;
+ e.spawnflags = self.spawnflags;
+ e.noalign = self.noalign;
+ setorigin(e, self.origin);
return true;
}
MUTATOR_HOOKFUNCTION(lms, ItemTouch)
{SELFPARAM();
- // give extra lives for mega health
- if (self.items & ITEM_HealthMega.m_itemid)
+ if(self.itemdef == ITEM_ExtraLife)
{
Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
PlayerScore_Add(other, SP_LMS_LIVES, autocvar_g_lms_extra_lives);
+ return MUT_ITEMTOUCH_PICKUP;
}
return MUT_ITEMTOUCH_CONTINUE;
}
}
-void SUB_Remove();
-
void pathlib_showsquare(vector where,float goodsquare,float _lifetime)
{
entity s;
s = spawn();
s.alpha = 0.25;
- s.think = SUB_Remove;
+ s.think = SUB_Remove_self;
s.nextthink = _lifetime;
s.scale = pathlib_gridsize / 512.001;
s.solid = SOLID_NOT;
e = spawn();
e.alpha = 0.25;
- e.think = SUB_Remove;
+ e.think = SUB_Remove_self;
e.nextthink = _lifetime;
e.scale = pathlib_gridsize / 512;
e.solid = SOLID_NOT;
e = findchainentity(owner, start);
while(e)
{
- e.think = SUB_Remove;
+ e.think = SUB_Remove_self;
e.nextthink = time;
e = e.chain;
}
void dumpnode(entity n)
{
n.is_path_node = false;
- n.think = SUB_Remove;
+ n.think = SUB_Remove_self;
n.nextthink = time;
}
node = spawn();
- node.think = SUB_Remove;
+ node.think = SUB_Remove_self;
node.nextthink = time + PATHLIB_NODEEXPIRE;
node.is_path_node = true;
node.owner = openlist;
*/
// PLAYERS use different math
-#ifndef POSITIVE_PITCH_IS_DOWN
+#if !(POSITIVE_PITCH_IS_DOWN)
ang.x = -ang.x;
#endif
//print("GOOD path: ", vtos(ang), "\n");
}
-#ifndef POSITIVE_PITCH_IS_DOWN
+#if !(POSITIVE_PITCH_IS_DOWN)
ang.x = -ang.x;
#endif
ang.z = vangle.z;
#include "cl_client.qc"
#include "cl_impulse.qc"
#include "cl_player.qc"
-#include "ent_cs.qc"
#include "g_damage.qc"
#include "g_hook.qc"
// #include "g_lights.qc" // TODO: was never used
#include "../common/campaign_file.qc"
#include "../common/campaign_setup.qc"
#include "../common/effects/effectinfo.qc"
+#include "../common/ent_cs.qc"
#include "../common/mapinfo.qc"
#include "../common/minigames/minigames.qc"
#include "../common/minigames/sv_minigames.qc"
#include "../common/viewloc.qc"
#include "../common/deathtypes/all.qc"
-#include "../common/buffs/all.qc"
#include "../common/effects/all.qc"
#include "../common/gamemodes/all.qc"
#include "../common/items/all.qc"
#include "../common/monsters/all.qc"
-#include "../common/nades/all.qc"
#include "../common/turrets/all.qc"
#include "../common/vehicles/all.qc"
#include "../common/weapons/all.qc"
{
if (i == RANKINGS_CNT)
{
- db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), string_null);
- db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), string_null);
+ db_remove(ServerProgsDB, strcat(map, rr, "time", ftos(i)));
+ db_remove(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)));
}
else
{
other.race_checkpoint = race_NextCheckpoint(self.race_checkpoint);
other.race_started = 1;
- race_SendTime(other, self.race_checkpoint, other.race_movetime, !!other.race_laptime);
+ race_SendTime(other, self.race_checkpoint, other.race_movetime, boolean(other.race_laptime));
if(!self.race_checkpoint) // start line
{
if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOSTEPS))
{
if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
- GlobalSound(globalsound_metalstep, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+ GlobalSound(GS_STEP_METAL, CH_PLAYER, VOICETYPE_PLAYERSOUND);
else
- GlobalSound(globalsound_step, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+ GlobalSound(GS_STEP, CH_PLAYER, VOICETYPE_PLAYERSOUND);
}
}
}
{
wi = get_weaponinfo(i);
- if (!(player.weapons & WepSet_FromWeapon(i)))
+ if (!(player.weapons & (wi.m_wepset)))
continue;
if(wi.items & ITEM_Shells.m_itemid)
if(this.angles != '0 0 0')
this.SendFlags |= ISF_ANGLES;
- this.reset = Item_Reset_self;
+ this.reset = Item_Reset;
// it's a level item
if(this.spawnflags & 1)
this.noalign = 1;
s = W_UndeprecateName(argv(i));
if(s == e.netname)
{
- self.weapons |= WepSet_FromWeapon(j);
+ self.weapons |= (e.m_wepset);
if(self.spawnflags == 0 || self.spawnflags == 2) {
Weapon w = get_weaponinfo(e.weapon);
w.wr_init(w);
}
self.netname = "";
- self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_UNLIMITED_WEAPON_AMMO), "unlimited_weapon_ammo");
- self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons");
- self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.strength_finished * !!(self.items & ITEM_Strength.m_itemid), "strength");
- self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.invincible_finished * !!(self.items & ITEM_Shield.m_itemid), "invincible");
- self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.superweapons_finished * !!(self.items & IT_SUPERWEAPON), "superweapons");
- self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & ITEM_Jetpack.m_itemid), "jetpack");
- self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & ITEM_JetpackRegen.m_itemid), "fuel_regen");
+ self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, boolean(self.items & IT_UNLIMITED_WEAPON_AMMO), "unlimited_weapon_ammo");
+ self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, boolean(self.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons");
+ self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.strength_finished * boolean(self.items & ITEM_Strength.m_itemid), "strength");
+ self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.invincible_finished * boolean(self.items & ITEM_Shield.m_itemid), "invincible");
+ self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.superweapons_finished * boolean(self.items & IT_SUPERWEAPON), "superweapons");
+ self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, boolean(self.items & ITEM_Jetpack.m_itemid), "jetpack");
+ self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, boolean(self.items & ITEM_JetpackRegen.m_itemid), "fuel_regen");
if(self.ammo_shells != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_shells), "shells");
if(self.ammo_nails != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_nails), "nails");
if(self.ammo_rockets != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_rockets), "rockets");
{
e = get_weaponinfo(j);
if(e.weapon)
- self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.weapons & WepSet_FromWeapon(j)), e.netname);
+ self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.weapons & (e.m_wepset)), e.netname);
}
}
self.netname = strzone(self.netname);
float GiveWeapon(entity e, float wpn, float op, float val)
{
WepSet v0, v1;
- v0 = (e.weapons & WepSet_FromWeapon(wpn));
+ WepSet s = WepSet_FromWeapon(wpn);
+ v0 = (e.weapons & s);
switch(op)
{
case OP_SET:
if(val > 0)
- e.weapons |= WepSet_FromWeapon(wpn);
+ e.weapons |= s;
else
- e.weapons &= ~WepSet_FromWeapon(wpn);
+ e.weapons &= ~s;
break;
case OP_MIN:
case OP_PLUS:
if(val > 0)
- e.weapons |= WepSet_FromWeapon(wpn);
+ e.weapons |= s;
break;
case OP_MAX:
if(val <= 0)
- e.weapons &= ~WepSet_FromWeapon(wpn);
+ e.weapons &= ~s;
break;
case OP_MINUS:
if(val > 0)
- e.weapons &= ~WepSet_FromWeapon(wpn);
+ e.weapons &= ~s;
break;
}
- v1 = (e.weapons & WepSet_FromWeapon(wpn));
+ v1 = (e.weapons & s);
return (v0 != v1);
}
if(wi.weapon)
{
POSTGIVE_WEAPON(e, j, SND(WEAPONPICKUP), string_null);
- if (!(save_weapons & WepSet_FromWeapon(j)))
- if(e.weapons & WepSet_FromWeapon(j)) {
+ if (!(save_weapons & (wi.m_wepset)))
+ if(e.weapons & (wi.m_wepset)) {
Weapon w = get_weaponinfo(wi.weapon);
w.wr_init(w);
}
#include "../common/weapons/all.qh"
-#include "../common/buffs/all.qh"
spawnfunc(weapon_crylink);
spawnfunc(weapon_electro);
else if (targ.classname == "item_health_mega")
self.health = 200;
//remove(targ); // removing ents in init functions causes havoc, workaround:
- targ.think = SUB_Remove;
+ targ.think = SUB_Remove_self;
targ.nextthink = time;
}
self.spawnflags = 2;
spawnfunc(item_flight)
{
- if(!cvar("g_buffs") || !cvar("g_buffs_flight"))
- spawnfunc_item_jetpack(this);
- else
- buff_Init_Compat(self, BUFF_FLIGHT);
+ spawnfunc_item_jetpack(this);
}
.float notteam;
// since this is an engine function, and gamecode doesn't have any calls earlier than this, do the connecting message here
if(!IS_CLIENT(self))
- Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_CONNECTING, self.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_CONNECTING, self.netname);
SetPlayerTeam(self, dteam, steam, !IS_CLIENT(self));
{
weaponwant = stof(car(rest)); rest = cdr(rest);
wep = get_weaponinfo(weaponwant);
- wepset = WepSet_FromWeapon(weaponwant);
+ wepset = wep.m_wepset;
if(imp >= 0)
if(wep.impulse != imp)
continue;
float i, have_other = false;
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
{
+ Weapon e = get_weaponinfo(i);
if(i != weaponwant)
- if((get_weaponinfo(i)).impulse == imp || imp < 0)
- if((pl.weapons & WepSet_FromWeapon(i)) || (weaponsInMap & WepSet_FromWeapon(i)))
+ if(e.impulse == imp || imp < 0)
+ if((pl.weapons & (e.m_wepset)) || (weaponsInMap & (e.m_wepset)))
have_other = true;
}
{
weaponwant = stof(car(rest)); rest = cdr(rest);
wep = get_weaponinfo(weaponwant);
- wepset = WepSet_FromWeapon(weaponwant);
+ wepset = wep.m_wepset;
if(imp >= 0)
if(wep.impulse != imp)
continue;
float i, have_other = false;
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
{
+ Weapon w = get_weaponinfo(i);
if(i != weaponwant)
- if((get_weaponinfo(i)).impulse == imp || imp < 0)
- if((pl.weapons & WepSet_FromWeapon(i)) || (weaponsInMap & WepSet_FromWeapon(i)))
+ if(w.impulse == imp || imp < 0)
+ if((pl.weapons & (w.m_wepset)) || (weaponsInMap & (w.m_wepset)))
have_other = true;
}
void W_SwitchToOtherWeapon(entity pl)
{
// hack to ensure it switches to an OTHER weapon (in case the other fire mode still has ammo, we want that anyway)
- float w, ww;
- w = pl.weapon;
- if(pl.weapons & WepSet_FromWeapon(w))
+ int ww;
+ WepSet set = WepSet_FromWeapon(pl.weapon);
+ if(pl.weapons & set)
{
- pl.weapons &= ~WepSet_FromWeapon(w);
+ pl.weapons &= ~set;
ww = w_getbestweapon(pl);
- pl.weapons |= WepSet_FromWeapon(w);
+ pl.weapons |= set;
}
else
ww = w_getbestweapon(pl);
{
float superweapons = 1;
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
- if(WepSet_FromWeapon(i) & WEPSET_SUPERWEAPONS)
- if(own.weapons & WepSet_FromWeapon(i))
- ++superweapons;
+ {
+ WepSet set = WepSet_FromWeapon(i);
+ if ((set & WEPSET_SUPERWEAPONS) && (own.weapons & set)) ++superweapons;
+ }
if(superweapons <= 1)
{
wep.superweapons_finished = own.superweapons_finished;
if(!W_IsWeaponThrowable(w))
return;
- if(!(self.weapons & WepSet_FromWeapon(w)))
- return;
- self.weapons &= ~WepSet_FromWeapon(w);
+ WepSet set = WepSet_FromWeapon(w);
+ if(!(self.weapons & set)) return;
+ self.weapons &= ~set;
W_SwitchWeapon_Force(self, w_getbestweapon(self));
string a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo);
--- /dev/null
+// This quickmenu example file can be loaded by setting
+// hud_panel_quickmenu_file quickmenu_example.txt
+// and executing "quickmenu file"
+// For more options see "quickmenu help"
+
+"Chat"
+ "nice one" "say :-) / nice one"
+ "good game" "say good game"
+ "hi / good luck" "say hi / good luck and have fun"
+"Chat"
+
+"Settings"
+ // nested submenu
+ "Sound settings"
+ "Hit sound" "toggle cl_hitsound"
+ "Chat sound" "toggle cl_chatsound"
+ "Sound settings"
+
+ // A toggle command displays a checkbox showing the current cvar's state
+ "enable 3rd person view" "toggle chase_active"
+ // it's possible to invert the meaning of the checkbox by inverting the
+ // parameters of toggle from the implicit 1 0 to 0 1
+ "disable 3rd person view" "toggle chase_active 0 1"
+"Settings"
+
+"screenshot" "wait; screenshot"
+
+// Commands that accept a player's name as parameter (%s), followed by one of
+// these special keywords:
+// ALLPLAYERS_BUT_ME
+// ALLPLAYERS
+// OWNTEAMPLAYERS_BUT_ME
+// OWNTEAMPLAYERS
+// ENEMYTEAMPLAYERS
+// lets you pick a player's name from a list:
+"private chat with:" "commandmode tell \"%s\"" ALLPLAYERS_BUT_ME