Merge branch 'master' into Lyberta/StandaloneOverkillWeapons
authorLyberta <lyberta@lyberta.net>
Tue, 29 Aug 2017 00:46:57 +0000 (03:46 +0300)
committerLyberta <lyberta@lyberta.net>
Tue, 29 Aug 2017 00:46:57 +0000 (03:46 +0300)
162 files changed:
.gitlab-ci.yml
CMakeLists.txt
balance-mario.cfg
balance-overkill.cfg
balance-samual.cfg
balance-xdf.cfg
balance-xonotic.cfg
balance-xpm.cfg
commands.cfg
defaultClient.cfg
defaultOverkill.cfg
defaultServer.cfg
defaultXonotic.cfg
gamemodes-server.cfg
mutators.cfg
qcsrc/Makefile
qcsrc/client/bgmscript.qc
qcsrc/client/commands/cl_cmd.qc
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/quickmenu.qc
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/hud/panel/vote.qc
qcsrc/client/main.qc
qcsrc/client/mapvoting.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/view.qc
qcsrc/common/command/generic.qc
qcsrc/common/command/rpn.qc
qcsrc/common/debug.qh
qcsrc/common/effects/effectinfo.qc
qcsrc/common/gamemodes/_mod.inc
qcsrc/common/gamemodes/_mod.qh
qcsrc/common/gamemodes/gamemode/nexball/_mod.inc
qcsrc/common/gamemodes/gamemode/nexball/_mod.qh
qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
qcsrc/common/gamemodes/gamemode/nexball/sv_weapon.qc [new file with mode: 0644]
qcsrc/common/gamemodes/gamemode/nexball/sv_weapon.qh [new file with mode: 0644]
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qh
qcsrc/common/gamemodes/rules.qc [new file with mode: 0644]
qcsrc/common/gamemodes/rules.qh [new file with mode: 0644]
qcsrc/common/gamemodes/sv_rules.qc [new file with mode: 0644]
qcsrc/common/gamemodes/sv_rules.qh [new file with mode: 0644]
qcsrc/common/items/all.qh
qcsrc/common/items/item.qh
qcsrc/common/items/item/pickup.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/common/minigames/minigame/bd.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/monsters/sv_spawn.qc
qcsrc/common/mutators/base.qh
qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc
qcsrc/common/mutators/mutator/damagetext/sv_damagetext.qc
qcsrc/common/mutators/mutator/dodging/sv_dodging.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/mutators/mutator/new_toys/sv_new_toys.qc
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/physical_items/sv_physical_items.qc
qcsrc/common/mutators/mutator/sandbox/sv_sandbox.qc
qcsrc/common/mutators/mutator/vampire/sv_vampire.qc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
qcsrc/common/notifications/all.qc
qcsrc/common/notifications/all.qh
qcsrc/common/physics/player.qc
qcsrc/common/playerstats.qc
qcsrc/common/t_items.qc
qcsrc/common/t_items.qh
qcsrc/common/triggers/func/button.qc
qcsrc/common/triggers/func/rotating.qc
qcsrc/common/triggers/target/spawn.qc
qcsrc/common/triggers/teleporters.qc
qcsrc/common/triggers/trigger/disablerelay.qc
qcsrc/common/triggers/trigger/viewloc.qc
qcsrc/common/turrets/all.qh
qcsrc/common/turrets/cl_turrets.qc
qcsrc/common/turrets/config.qc
qcsrc/common/util.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/all.qh
qcsrc/common/weapons/calculations.qc
qcsrc/common/weapons/config.qc
qcsrc/common/weapons/weapon.qh
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/machinegun.qh
qcsrc/common/weapons/weapon/rifle.qh
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/lib/_all.inc
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/log.qh
qcsrc/lib/math.qh
qcsrc/lib/test.qc
qcsrc/lib/urllib.qc
qcsrc/lib/warpzone/server.qc
qcsrc/menu/command/menu_cmd.qc
qcsrc/menu/menu.qc
qcsrc/menu/xonotic/maplist.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/skinlist.qc
qcsrc/menu/xonotic/slider_decibels.qc
qcsrc/menu/xonotic/util.qc
qcsrc/server/bot/default/aim.qc
qcsrc/server/bot/default/bot.qc
qcsrc/server/bot/default/scripting.qc
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/campaign.qc
qcsrc/server/cheats.qc
qcsrc/server/client.qc
qcsrc/server/command/banning.qc
qcsrc/server/command/common.qc
qcsrc/server/command/radarmap.qc
qcsrc/server/command/radarmap.qh
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/g_world.qh
qcsrc/server/impulse.qc
qcsrc/server/ipban.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/gamemode.qh
qcsrc/server/mutators/mutator/gamemode_assault.qc
qcsrc/server/mutators/mutator/gamemode_assault.qh
qcsrc/server/mutators/mutator/gamemode_ca.qc
qcsrc/server/mutators/mutator/gamemode_ca.qh
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qh
qcsrc/server/mutators/mutator/gamemode_cts.qc
qcsrc/server/mutators/mutator/gamemode_cts.qh
qcsrc/server/mutators/mutator/gamemode_deathmatch.qh
qcsrc/server/mutators/mutator/gamemode_domination.qc
qcsrc/server/mutators/mutator/gamemode_domination.qh
qcsrc/server/mutators/mutator/gamemode_freezetag.qc
qcsrc/server/mutators/mutator/gamemode_freezetag.qh
qcsrc/server/mutators/mutator/gamemode_invasion.qc
qcsrc/server/mutators/mutator/gamemode_invasion.qh
qcsrc/server/mutators/mutator/gamemode_keepaway.qc
qcsrc/server/mutators/mutator/gamemode_keepaway.qh
qcsrc/server/mutators/mutator/gamemode_keyhunt.qc
qcsrc/server/mutators/mutator/gamemode_keyhunt.qh
qcsrc/server/mutators/mutator/gamemode_lms.qc
qcsrc/server/mutators/mutator/gamemode_lms.qh
qcsrc/server/mutators/mutator/gamemode_race.qc
qcsrc/server/mutators/mutator/gamemode_race.qh
qcsrc/server/mutators/mutator/gamemode_tdm.qc
qcsrc/server/mutators/mutator/gamemode_tdm.qh
qcsrc/server/player.qc
qcsrc/server/playerdemo.qc
qcsrc/server/portals.qc
qcsrc/server/race.qc
qcsrc/server/scores.qh
qcsrc/server/scores_rules.qc
qcsrc/server/spawnpoints.qc
qcsrc/server/sv_main.qc
qcsrc/server/teamplay.qc
qcsrc/server/teamplay.qh
qcsrc/server/weapons/common.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponstats.qc
scripts/ok_nade_counter.shader

index 5427860..9305f52 100644 (file)
@@ -29,7 +29,7 @@ test_sv_game:
     - wget -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints
     - wget -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache
     - make
-    - EXPECT=585cfa6d62ce59f4854bedfce7c51c20
+    - EXPECT=ed9be8d1b1a544f89bcdd7d36876fede
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index 5ef6db7..2e5fc79 100644 (file)
@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
 project(xonotic-data ASM)
 
+set(all qc-all)
+add_custom_target(${all})
+
 set(checks qc-checks)
 add_custom_target(${checks})
 
@@ -73,14 +76,17 @@ set_source_files_properties(
 )
 
 add_executable(csprogs qcsrc/client/progs.inc)
+add_dependencies(${all} csprogs)
 add_dependencies(csprogs ${checks})
 target_compile_definitions(csprogs PRIVATE -DGAMEQC -DCSQC)
 
 add_executable(progs qcsrc/server/progs.inc)
+add_dependencies(${all} progs)
 add_dependencies(progs ${checks})
 target_compile_definitions(progs PRIVATE -DGAMEQC -DSVQC)
 
 add_executable(menu qcsrc/menu/progs.inc)
+add_dependencies(${all} menu)
 add_dependencies(menu ${checks})
 target_compile_definitions(menu PRIVATE -DMENUQC)
 
index 42cf311..a8f59a8 100644 (file)
@@ -114,7 +114,7 @@ set g_balance_pause_health_rot 1
 set g_balance_pause_health_rot_spawn 5
 set g_balance_health_regenstable 100
 set g_balance_health_rotstable 100
-set g_balance_health_limit 999
+set g_balance_health_limit 200
 set g_balance_armor_regen 0
 set g_balance_armor_regenlinear 0
 set g_balance_armor_rot 0.02
@@ -123,7 +123,7 @@ set g_balance_pause_armor_rot 1
 set g_balance_pause_armor_rot_spawn 5
 set g_balance_armor_regenstable 100
 set g_balance_armor_rotstable 100
-set g_balance_armor_limit 999
+set g_balance_armor_limit 200
 set g_balance_armor_blockpercent 0.7
 set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
 set g_balance_fuel_regenlinear 0
@@ -134,7 +134,7 @@ set g_balance_pause_fuel_rot 5
 set g_balance_pause_fuel_rot_spawn 10
 set g_balance_fuel_regenstable 50
 set g_balance_fuel_rotstable 100
-set g_balance_fuel_limit 999
+set g_balance_fuel_limit 100
 // }}}
 
 // {{{ misc
index fc99616..3f02565 100644 (file)
@@ -114,7 +114,7 @@ set g_balance_pause_health_rot 1
 set g_balance_pause_health_rot_spawn 5
 set g_balance_health_regenstable 100
 set g_balance_health_rotstable 200
-set g_balance_health_limit 999
+set g_balance_health_limit 200
 set g_balance_armor_regen 0
 set g_balance_armor_regenlinear 0
 set g_balance_armor_rot 0
@@ -123,7 +123,7 @@ set g_balance_pause_armor_rot 5
 set g_balance_pause_armor_rot_spawn 5
 set g_balance_armor_regenstable 100
 set g_balance_armor_rotstable 0
-set g_balance_armor_limit 999
+set g_balance_armor_limit 200
 set g_balance_armor_blockpercent 0.6
 set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
 set g_balance_fuel_regenlinear 0
@@ -134,7 +134,7 @@ set g_balance_pause_fuel_rot 5
 set g_balance_pause_fuel_rot_spawn 10
 set g_balance_fuel_regenstable 50
 set g_balance_fuel_rotstable 100
-set g_balance_fuel_limit 999
+set g_balance_fuel_limit 100
 // }}}
 
 // {{{ misc
index 4357eff..52fd03d 100644 (file)
@@ -114,7 +114,7 @@ set g_balance_pause_health_rot 1
 set g_balance_pause_health_rot_spawn 5
 set g_balance_health_regenstable 100
 set g_balance_health_rotstable 100
-set g_balance_health_limit 999
+set g_balance_health_limit 200
 set g_balance_armor_regen 0
 set g_balance_armor_regenlinear 0
 set g_balance_armor_rot 0.04
@@ -123,7 +123,7 @@ set g_balance_pause_armor_rot 1
 set g_balance_pause_armor_rot_spawn 5
 set g_balance_armor_regenstable 100
 set g_balance_armor_rotstable 100
-set g_balance_armor_limit 999
+set g_balance_armor_limit 200
 set g_balance_armor_blockpercent 0.6
 set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
 set g_balance_fuel_regenlinear 0
@@ -134,7 +134,7 @@ set g_balance_pause_fuel_rot 5
 set g_balance_pause_fuel_rot_spawn 10
 set g_balance_fuel_regenstable 50
 set g_balance_fuel_rotstable 100
-set g_balance_fuel_limit 999
+set g_balance_fuel_limit 100
 // }}}
 
 // {{{ misc
index a7d6b43..4d26972 100644 (file)
@@ -114,7 +114,7 @@ set g_balance_pause_health_rot 1
 set g_balance_pause_health_rot_spawn 5
 set g_balance_health_regenstable 100
 set g_balance_health_rotstable 100
-set g_balance_health_limit 999
+set g_balance_health_limit 200
 set g_balance_armor_regen 0
 set g_balance_armor_regenlinear 0
 set g_balance_armor_rot 0.02
@@ -123,7 +123,7 @@ set g_balance_pause_armor_rot 1
 set g_balance_pause_armor_rot_spawn 5
 set g_balance_armor_regenstable 100
 set g_balance_armor_rotstable 100
-set g_balance_armor_limit 999
+set g_balance_armor_limit 200
 set g_balance_armor_blockpercent 0.7
 set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
 set g_balance_fuel_regenlinear 0
@@ -134,7 +134,7 @@ set g_balance_pause_fuel_rot 5
 set g_balance_pause_fuel_rot_spawn 10
 set g_balance_fuel_regenstable 50
 set g_balance_fuel_rotstable 100
-set g_balance_fuel_limit 999
+set g_balance_fuel_limit 100
 // }}}
 
 // {{{ misc
index 5bd1536..fece8cd 100644 (file)
@@ -114,7 +114,7 @@ set g_balance_pause_health_rot 1
 set g_balance_pause_health_rot_spawn 5
 set g_balance_health_regenstable 100
 set g_balance_health_rotstable 100
-set g_balance_health_limit 999
+set g_balance_health_limit 200
 set g_balance_armor_regen 0
 set g_balance_armor_regenlinear 0
 set g_balance_armor_rot 0.02
@@ -123,7 +123,7 @@ set g_balance_pause_armor_rot 1
 set g_balance_pause_armor_rot_spawn 5
 set g_balance_armor_regenstable 100
 set g_balance_armor_rotstable 100
-set g_balance_armor_limit 999
+set g_balance_armor_limit 200
 set g_balance_armor_blockpercent 0.7
 set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
 set g_balance_fuel_regenlinear 0
@@ -134,7 +134,7 @@ set g_balance_pause_fuel_rot 5
 set g_balance_pause_fuel_rot_spawn 10
 set g_balance_fuel_regenstable 50
 set g_balance_fuel_rotstable 100
-set g_balance_fuel_limit 999
+set g_balance_fuel_limit 100
 // }}}
 
 // {{{ misc
index 5c14aa3..9849726 100644 (file)
@@ -114,7 +114,7 @@ set g_balance_pause_health_rot 1
 set g_balance_pause_health_rot_spawn 5
 set g_balance_health_regenstable 100
 set g_balance_health_rotstable 100
-set g_balance_health_limit 999
+set g_balance_health_limit 200
 set g_balance_armor_regen 0
 set g_balance_armor_regenlinear 0
 set g_balance_armor_rot 0.02
@@ -123,7 +123,7 @@ set g_balance_pause_armor_rot 1
 set g_balance_pause_armor_rot_spawn 5
 set g_balance_armor_regenstable 100
 set g_balance_armor_rotstable 100
-set g_balance_armor_limit 999
+set g_balance_armor_limit 200
 set g_balance_armor_blockpercent 0.7
 set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
 set g_balance_fuel_regenlinear 0
@@ -134,7 +134,7 @@ set g_balance_pause_fuel_rot 5
 set g_balance_pause_fuel_rot_spawn 10
 set g_balance_fuel_regenstable 50
 set g_balance_fuel_rotstable 100
-set g_balance_fuel_limit 999
+set g_balance_fuel_limit 100
 // }}}
 
 // {{{ misc
index 93b68f9..66ca90e 100644 (file)
@@ -185,6 +185,7 @@ alias skinmob "editmob skin ${* ?}"
 alias namemob "editmob name ${* ?}"
 alias movemob "editmob movetarget ${* ?}"
 alias butcher "editmob butcher ${* ?}"
+alias mobbutcher "editmob butcher ${* ?}"
 
 
 // ============================================================
@@ -209,7 +210,6 @@ alias gettaginfo           "qc_cmd_sv     gettaginfo           ${* ?}" // Get sp
 alias gotomap              "qc_cmd_sv     gotomap              ${* ?}" // Simple command to switch to another map
 alias lockteams            "qc_cmd_sv     lockteams            ${* ?}" // Disable the ability for players to switch or enter teams
 alias make_mapinfo         "qc_cmd_sv     make_mapinfo         ${* ?}" // Automatically rebuild mapinfo files
-alias mobbutcher           "qc_cmd_sv     mobbutcher           ${* ?}" // Remove all monsters on the map
 alias moveplayer           "qc_cmd_sv     moveplayer           ${* ?}" // Change the team/status of a player
 alias nospectators         "qc_cmd_sv     nospectators         ${* ?}" // Automatically remove spectators from a match
 alias playerdemo           "qc_cmd_sv     playerdemo           ${* ?}" // Control the ability to save demos of players
index f600b82..f08874c 100644 (file)
@@ -33,7 +33,6 @@ mod_q3bsp_lightmapmergepower 4
 _cl_color "112.211" // same effect as 112, but menuqc can detect this as the default and not intentionally set
 _cl_name ""
 seta _cl_gender 0 "storage cvar for current player gender (0 = undisclosed, 1 = male, 2 = female)"
-_cl_playermodel models/player/erebus.iqm
 _cl_playerskin 0
 
 seta cl_reticle 1 "enable zoom reticles"
@@ -269,7 +268,7 @@ r_shadow_realtime_world_lightmaps 1
 r_shadow_realtime_world_importlightentitiesfrommap 0 // Whether build process uses keepLights is nontransparent and may change, so better make keepLights not matter.
 cl_decals_fadetime 5
 cl_decals_time 1
-seta cl_gunalign 3 "Gun alignment; 1 = center (if allowed by g_shootfromclient) or right, 2 = center (if allowed by g_shootfromclient) or left, 3 = right only, 4 = left only"
+seta cl_gunalign 3 "Gun alignment; 1 = center, 3 = right, 4 = left; requires reconnect"
 seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
 seta cl_particlegibs 0 "simpler gibs"
 seta cl_gibs_damageforcescale 3.5 "force to push around gibs"
index 634943c..2444301 100644 (file)
@@ -8,6 +8,15 @@ exec physicsOverkill.cfg
 
 // general gameplay
 set g_overkill 1
+
+// hack - eventually, we should be able to choose overkill models in menu like for vanilla
+set sv_defaultcharacter 1
+set sv_defaultplayermodel "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm"
+set sv_defaultplayermodel_red "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm"
+set sv_defaultplayermodel_blue "models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm"
+set sv_defaultplayermodel_yellow "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm"
+set sv_defaultplayermodel_pink "models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm"
+
 set g_respawn_ghosts 0
 
 set g_nades 1
index ff1040b..d199d3a 100644 (file)
@@ -185,6 +185,9 @@ set g_weapon_throwable 1 "if set to 1, weapons can be dropped"
 set g_powerups -1 "if set to 0 the strength and shield (invincibility) will not spawn on the map, if 1 they will spawn in all game modes, -1 is game mode default"
 set g_use_ammunition 1 "if set to 0 all weapons have unlimited ammunition"
 set g_pickup_items -1 "if set to 0 all items (health, armor, ammo, weapons...) are removed from the map, if 1 they are forced to spawn"
+set g_pickup_respawntime_scaling_reciprocal 0 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to 0) can be used to achieve a constant number of items spawned *per player*"
+set g_pickup_respawntime_scaling_offset 0 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right - the results are not intuitive and I recommend plotting the respawn time and the number of items per player to see what's happening"
+set g_pickup_respawntime_scaling_linear 1 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly"
 set g_weaponarena "0"  "put in a list of weapons to enable a weapon arena mode, or try \"all\" or \"most\""
 set g_weaponarena_random "0"   "if set to a number, only that weapon count is given on every spawn (randomly)"
 set g_weaponarena_random_with_blaster "1"      "additionally, always provide the blaster in random weapon arena games"
index b3b23fe..eb6c72a 100644 (file)
@@ -29,6 +29,8 @@ exec defaultServer.cfg
 
 set ekg 0      "Throw huge amounts of gibs"
 
+_cl_playermodel "models/player/erebus.iqm"
+
 locs_enable 0
 pausable 0
 set samelevel 0 "when 1, always play the same level over and over again"
index 684edb3..6790a3b 100644 (file)
@@ -256,9 +256,9 @@ set g_ctf_flag_dropped_floatinwater 200 "move upwards while in water at this vel
 set g_ctf_throw 1 "throwing allows circumventing carrierkill score, so enable this with care!"
 set g_ctf_throw_angle_max 90 "maximum upwards angle you can throw the flag"
 set g_ctf_throw_angle_min -90 "minimum downwards angle you can throw the flag"
-set g_ctf_throw_punish_count 2
+set g_ctf_throw_punish_count 3
 set g_ctf_throw_punish_delay 30
-set g_ctf_throw_punish_time 5
+set g_ctf_throw_punish_time 10
 set g_ctf_throw_strengthmultiplier 2 "multiplier for velocity when you have the strength... essentially, throw the flag REALLY hard when you have the strength :D"
 set g_ctf_throw_velocity_forward 500 "how fast or far a player can throw the flag"
 set g_ctf_throw_velocity_up 200 "upwards velocity added upon initial throw"
@@ -521,3 +521,4 @@ set g_invasion_spawn_delay 0.25
 set g_invasion_spawnpoint_spawn_delay 0.5
 set g_invasion_teams 0 "number of teams in invasion (note: use mapinfo to set this)"
 set g_invasion_team_spawns 1 "use team spawns in teamplay invasion mode"
+set g_invasion_type 0 "type of invasion mode - 0: round-based, 1: hunting, 2: complete the stage (note: use mapinfo to set this)"
index 9e8460d..23c7243 100644 (file)
@@ -176,7 +176,7 @@ set g_random_gravity_negative 1000 "negative gravity multiplier"
 // =======
 set g_nades 0 "enable off-hand grenades"
 set g_nades_spread 0.04 "random spread offset of throw direction"
-set g_nades_throw_offset "0 0 0" "nade throwing offset"
+set g_nades_throw_offset "0 -25 0" "nade throwing offset"
 set g_nades_spawn 1 "give nades right away when player spawns rather than delaying entire refire"
 set g_nades_client_select 0 "allow client side selection of nade type"
 set g_nades_pickup 0 "allow picking up thrown nades (not your own)"
index bd17dad..bfea08b 100644 (file)
@@ -14,17 +14,17 @@ ENABLE_DEBUGTRACE ?= 0
 BUILD_MOD ?=
 
 ifndef ZIP
-       ifneq ($(shell which zip),)
+       ifneq ($(shell which zip 2>/dev/null),)
                ZIP := zip -9
        endif
-       ifneq ($(shell which 7z),)
+       ifneq ($(shell which 7z 2>/dev/null),)
                ZIP := 7z a -tzip -mx=9
        endif
-       ifneq ($(shell which 7za),)
+       ifneq ($(shell which 7za 2>/dev/null),)
                ZIP := 7za a -tzip -mx=9
        endif
     ifndef ZIP
-        $(warning "No zip in ($(PATH))")
+        $(warning "No zip / 7z / 7za in ($(PATH))")
         ZIP := : zip_not_found
     endif
 endif
index 4dc6204..2db9e54 100644 (file)
@@ -138,7 +138,7 @@ void BGMScript_InitEntity(entity e)
                e.bgmscriptline = e.bgmscriptline0 = i;
                if(i >= bgmscriptbufsize)
                {
-                       LOG_INFOF("ERROR: bgmscript does not define %s\n", e.bgmscript);
+                       LOG_INFOF("ERROR: bgmscript does not define %s", e.bgmscript);
                        strunzone(e.bgmscript);
                        e.bgmscript = string_null;
                }
index 6777eef..8faf0f3 100644 (file)
@@ -52,22 +52,22 @@ void LocalCommand_blurtest(int request)
                        blurtest_time1 = time + stof(argv(1));
                        blurtest_radius = stof(argv(2));
                        blurtest_power = stof(argv(3));
-                       LOG_INFO("Enabled blurtest\n");
+                       LOG_INFO("Enabled blurtest");
                        return;
                }
 
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd blurtest\n");
-                       LOG_INFO("  No arguments required.\n");
+                       LOG_INFO("Usage:^3 cl_cmd blurtest");
+                       LOG_INFO("  No arguments required.");
                        return;
                }
        }
        #else
        if (request)
        {
-               LOG_INFO("Blurtest is not enabled on this client.\n");
+               LOG_INFO("Blurtest is not enabled on this client.");
                return;
        }
        #endif
@@ -105,23 +105,25 @@ void LocalCommand_boxparticles(int request, int argc)
 
                default:
                {
-                       LOG_INFO("Incorrect parameters for ^2boxparticles^7\n");
+                       LOG_INFO("Incorrect parameters for ^2boxparticles^7");
                }
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 lv_cmd boxparticles effectname own org_from org_to, dir_from, dir_to, countmultiplier, flags\n");
-                       LOG_INFO("  'effectname' is the name of a particle effect in effectinfo.txt\n");
-                       LOG_INFO("  'own' is the entity number of the owner (negative for csqc ent, positive for svqc ent)\n");
-                       LOG_INFO("  'org_from' is the starting origin of the box\n");
-                       LOG_INFO("  'org_to' is the ending origin of the box\n");
-                       LOG_INFO("  'dir_from' is the minimum velocity\n");
-                       LOG_INFO("  'dir_to' is the maximum velocity\n");
-                       LOG_INFO("  'countmultiplier' defines a multiplier for the particle count (affects count only, not countabsolute or trailspacing)\n");
-                       LOG_INFO("  'flags' can contain:\n");
-                       LOG_INFO("    1 to respect globals particles_alphamin, particles_alphamax (set right before via prvm_globalset client)\n");
-                       LOG_INFO("    2 to respect globals particles_colormin, particles_colormax (set right before via prvm_globalset client)\n");
-                       LOG_INFO("    4 to respect globals particles_fade (set right before via prvm_globalset client)\n");
-                       LOG_INFO("    128 to draw a trail, not a box\n");
+                       LOG_INFO(
+                           "Usage:^3 lv_cmd boxparticles effectname own org_from org_to, dir_from, dir_to, countmultiplier, flags\n"
+                "  'effectname' is the name of a particle effect in effectinfo.txt\n"
+                "  'own' is the entity number of the owner (negative for csqc ent, positive for svqc ent)\n"
+                "  'org_from' is the starting origin of the box\n"
+                "  'org_to' is the ending origin of the box\n"
+                "  'dir_from' is the minimum velocity\n"
+                "  'dir_to' is the maximum velocity\n"
+                "  'countmultiplier' defines a multiplier for the particle count (affects count only, not countabsolute or trailspacing)\n"
+                "  'flags' can contain:\n"
+                "    1 to respect globals particles_alphamin, particles_alphamax (set right before via prvm_globalset client)\n"
+                "    2 to respect globals particles_colormin, particles_colormax (set right before via prvm_globalset client)\n"
+                "    4 to respect globals particles_fade (set right before via prvm_globalset client)\n"
+                "    128 to draw a trail, not a box\n"
+                       );
                        return;
                }
        }
@@ -146,13 +148,13 @@ void LocalCommand_create_scrshot_ent(int request)
                                fputs(fh, strcat("\"angles\" \"", strcat(ftos(view_angles.x), " ", ftos(view_angles.y), " ", ftos(view_angles.z)), "\"\n"));
                                fputs(fh, "}\n");
 
-                               LOG_INFO("Completed screenshot entity dump in ^2data/data/", path, MapInfo_Map_bspname, "_scrshot_ent.txt^7.\n");
+                               LOG_INFO("Completed screenshot entity dump in ^2data/data/", path, MapInfo_Map_bspname, "_scrshot_ent.txt^7.");
 
                                fclose(fh);
                        }
                        else
                        {
-                               LOG_INFO("^1Error: ^7Could not dump to file!\n");
+                               LOG_INFO("^1Error: ^7Could not dump to file!");
                        }
                        return;
                }
@@ -160,8 +162,8 @@ void LocalCommand_create_scrshot_ent(int request)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd create_scrshot_ent [path]\n");
-                       LOG_INFO("  Where 'path' can be the subdirectory of data/data in which the file is saved.\n");
+                       LOG_INFO("Usage:^3 cl_cmd create_scrshot_ent [path]");
+                       LOG_INFO("  Where 'path' can be the subdirectory of data/data in which the file is saved.");
                        return;
                }
        }
@@ -190,8 +192,8 @@ void LocalCommand_debugmodel(int request, int argc)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd debugmodel model\n");
-                       LOG_INFO("  Where 'model' is a string of the model name to use for the debug model.\n");
+                       LOG_INFO("Usage:^3 cl_cmd debugmodel model");
+                       LOG_INFO("  Where 'model' is a string of the model name to use for the debug model.");
                        return;
                }
        }
@@ -236,12 +238,12 @@ void LocalCommand_handlevote(int request, int argc)
 
                default:
                {
-                       LOG_INFO("Incorrect parameters for ^2handlevote^7\n");
+                       LOG_INFO("Incorrect parameters for ^2handlevote^7");
                }
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd handlevote vote\n");
-                       LOG_INFO("  Where 'vote' is the selection for either the current poll or uid2name.\n");
+                       LOG_INFO("Usage:^3 cl_cmd handlevote vote");
+                       LOG_INFO("  Where 'vote' is the selection for either the current poll or uid2name.");
                        return;
                }
        }
@@ -279,10 +281,10 @@ void LocalCommand_hud(int request, int argc)
                                {
                                        if (argv(2) == "help")
                                        {
-                                               LOG_INFO(" quickmenu [[default | file | \"\"] submenu file]\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");
-                                               LOG_INFO("A file name can also be given to open a different quickmenu\n");
+                                               LOG_INFO(" quickmenu [[default | file | \"\"] submenu file]");
+                                               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.");
+                                               LOG_INFO("A submenu name can be given to open the quickmenu directly in a submenu; it requires to specify 'default', 'file' or '\"\"' option.");
+                                               LOG_INFO("A file name can also be given to open a different quickmenu");
                                                return;
                                        }
                                        string file = ((argv(4) == "") ? autocvar_hud_panel_quickmenu_file : argv(4));
@@ -337,16 +339,16 @@ void LocalCommand_hud(int request, int argc)
 
                default:
                {
-                       LOG_INFO("Incorrect parameters for ^2hud^7\n");
+                       LOG_INFO("Incorrect parameters for ^2hud^7");
                }
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd hud action [configname | radartoggle | layout]\n");
-                       LOG_INFO("  Where 'action' is the command to complete,\n");
-                       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("  Full list of commands here: \"configure, quickmenu, minigame, save, scoreboard_columns_help, scoreboard_columns_set, radar.\"\n");
+                       LOG_INFO("Usage:^3 cl_cmd hud action [configname | radartoggle | layout]");
+                       LOG_INFO("  Where 'action' is the command to complete,");
+                       LOG_INFO("  'configname' is the name to save to for \"save\" action,");
+                       LOG_INFO("  'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action,");
+                       LOG_INFO("  and 'layout' is how to organize the scoreboard columns for the set action.");
+                       LOG_INFO("  Full list of commands here: \"configure, quickmenu, minigame, save, scoreboard_columns_help, scoreboard_columns_set, radar.\"");
                        return;
                }
        }
@@ -368,12 +370,12 @@ void LocalCommand_localprint(int request, int argc)
 
                default:
                {
-                       LOG_INFO("Incorrect parameters for ^2localprint^7\n");
+                       LOG_INFO("Incorrect parameters for ^2localprint^7");
                }
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd localprint \"message\"\n");
-                       LOG_INFO("  'message' is the centerprint message to send to yourself.\n");
+                       LOG_INFO("Usage:^3 cl_cmd localprint \"message\"");
+                       LOG_INFO("  'message' is the centerprint message to send to yourself.");
                        return;
                }
        }
@@ -395,12 +397,12 @@ void LocalCommand_mv_download(int request, int argc)
 
                default:
                {
-                       LOG_INFO("Incorrect parameters for ^2mv_download^7\n");
+                       LOG_INFO("Incorrect parameters for ^2mv_download^7");
                }
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd mv_download mapid\n");
-                       LOG_INFO("  Where 'mapid' is the id number of the map to request an image of on the map vote selection menu.\n");
+                       LOG_INFO("Usage:^3 cl_cmd mv_download mapid");
+                       LOG_INFO("  Where 'mapid' is the id number of the map to request an image of on the map vote selection menu.");
                        return;
                }
        }
@@ -432,12 +434,12 @@ void LocalCommand_sendcvar(int request, int argc)
 
                default:
                {
-                       LOG_INFO("Incorrect parameters for ^2sendcvar^7\n");
+                       LOG_INFO("Incorrect parameters for ^2sendcvar^7");
                }
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd sendcvar <cvar>\n");
-                       LOG_INFO("  Where 'cvar' is the cvar plus arguments to send to the server.\n");
+                       LOG_INFO("Usage:^3 cl_cmd sendcvar <cvar>");
+                       LOG_INFO("  Where 'cvar' is the cvar plus arguments to send to the server.");
                        return;
                }
        }
@@ -484,7 +486,7 @@ CLIENT_COMMAND(sendcvar, "Send a cvar to the server (like weaponpriority)") { Lo
 
 void LocalCommand_macro_help()
 {
-       FOREACH(CLIENT_COMMANDS, true, LOG_INFOF("  ^2%s^7: %s\n", it.m_name, it.m_description));
+       FOREACH(CLIENT_COMMANDS, true, LOG_INFOF("  ^2%s^7: %s", it.m_name, it.m_description));
 }
 
 bool LocalCommand_macro_command(int argc, string command)
@@ -531,14 +533,14 @@ void GameCommand(string command)
        {
                if (argc == 1)
                {
-                       LOG_INFO("\nClient console commands:\n");
+                       LOG_INFO("Client console commands:");
                        LocalCommand_macro_help();
 
-                       LOG_INFO("\nGeneric commands shared by all programs:\n");
+                       LOG_INFO("\nGeneric commands shared by all programs:");
                        GenericCommand_macro_help();
 
-                       LOG_INFO("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are listed above.\n");
-                       LOG_INFO("For help about a specific command, type cl_cmd help COMMAND\n");
+                       LOG_INFO("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are listed above.");
+                       LOG_INFO("For help about a specific command, type cl_cmd help COMMAND");
 
                        return;
                }
@@ -558,7 +560,7 @@ void GameCommand(string command)
           ) return;
 
        // nothing above caught the command, must be invalid
-       LOG_INFO(((command != "") ? strcat("Unknown client command \"", command, "\"") : "No command provided"), ". For a list of supported commands, try cl_cmd help.\n");
+       LOG_INFO(((command != "") ? strcat("Unknown client command \"", command, "\"") : "No command provided"), ". For a list of supported commands, try cl_cmd help.");
 }
 
 
index 9893b8a..6499a68 100644 (file)
@@ -134,7 +134,7 @@ void CSQCPlayer_ModelAppearance_PostUpdate(entity this)
                this.forceplayermodels_isgoodmodel = fexists(this.forceplayermodels_savemodel);
                this.forceplayermodels_isgoodmodel_mdl = this.forceplayermodels_savemodel;
                if(!this.forceplayermodels_isgoodmodel)
-                       LOG_INFOF("Warning: missing model %s has been used\n", this.forceplayermodels_savemodel);
+                       LOG_INFOF("Warning: missing model %s has been used", this.forceplayermodels_savemodel);
        }
 }
 void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
index a1f1cc7..ec07ee4 100644 (file)
@@ -239,11 +239,11 @@ void HUD_Panel_ExportCfg(string cfgname)
 
                HUD_Write("menu_sync\n"); // force the menu to reread the cvars, so that the dialogs are updated
 
-               LOG_INFOF(_("^2Successfully exported to %s! (Note: It's saved in data/data/)\n"), filename);
+               LOG_INFOF(_("^2Successfully exported to %s! (Note: It's saved in data/data/)"), filename);
                fclose(fh);
        }
        else
-               LOG_INFOF(_("^1Couldn't write to %s\n"), filename);
+               LOG_INFOF(_("^1Couldn't write to %s"), filename);
 }
 
 void HUD_Configure_Exit_Force()
index 3233d1b..9af8673 100644 (file)
@@ -83,12 +83,12 @@ bool QuickMenu_Open(string mode, string submenu, string file)
        if(mode == "file")
        {
                if(file == "" || file == "0")
-                       LOG_INFO("No file name is set in hud_panel_quickmenu_file, loading default quickmenu\n");
+                       LOG_INFO("No file name is set in hud_panel_quickmenu_file, loading default quickmenu");
                else
                {
                        fh = fopen(file, FILE_READ);
                        if(fh < 0)
-                               LOG_INFOF("Couldn't open file \"%s\", loading default quickmenu\n", file);
+                               LOG_INFOF("Couldn't open file \"%s\", loading default quickmenu", file);
                }
                if(fh < 0)
                        mode = "default";
index 34ecd83..8e0d0f0 100644 (file)
@@ -153,13 +153,12 @@ float SetTeam(entity pl, float Team);
 //float lastpnum;
 void Scoreboard_UpdatePlayerTeams()
 {
-       float Team;
        entity pl, tmp;
        //int num = 0;
        for(pl = players.sort_next; pl; pl = pl.sort_next)
        {
                //num += 1;
-               Team = entcs_GetScoreTeam(pl.sv_entnum);
+               int Team = entcs_GetScoreTeam(pl.sv_entnum);
                if(SetTeam(pl, Team))
                {
                        tmp = pl.sort_prev;
@@ -296,48 +295,48 @@ void Scoreboard_UpdateTeamPos(entity Team)
 
 void Cmd_Scoreboard_Help()
 {
-       LOG_INFO(_("You can modify the scoreboard using the ^2scoreboard_columns_set command.\n"));
-       LOG_INFO(_("^3|---------------------------------------------------------------|\n"));
-       LOG_INFO(_("Usage:\n"));
-       LOG_INFO(_("^2scoreboard_columns_set default\n"));
-       LOG_INFO(_("^2scoreboard_columns_set ^7field1 field2 ...\n"));
-       LOG_INFO(_("The following field names are recognized (case insensitive):\n"));
-       LOG_INFO(_("You can use a ^3|^7 to start the right-aligned fields.\n"));
-       LOG_INFO("\n");
-
-       LOG_INFO(_("^3name^7 or ^3nick^7             Name of a player\n"));
-       LOG_INFO(_("^3ping^7                     Ping time\n"));
-       LOG_INFO(_("^3pl^7                       Packet loss\n"));
-       LOG_INFO(_("^3elo^7                      Player ELO\n"));
-       LOG_INFO(_("^3kills^7                    Number of kills\n"));
-       LOG_INFO(_("^3deaths^7                   Number of deaths\n"));
-       LOG_INFO(_("^3suicides^7                 Number of suicides\n"));
-       LOG_INFO(_("^3frags^7                    kills - suicides\n"));
-       LOG_INFO(_("^3kd^7                       The kill-death ratio\n"));
-       LOG_INFO(_("^3dmg^7                      The total damage done\n"));
-       LOG_INFO(_("^3dmgtaken^7                 The total damage taken\n"));
-       LOG_INFO(_("^3sum^7                      frags - deaths\n"));
-       LOG_INFO(_("^3caps^7                     How often a flag (CTF) or a key (KeyHunt) was captured\n"));
-       LOG_INFO(_("^3pickups^7                  How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up\n"));
-       LOG_INFO(_("^3captime^7                  Time of fastest cap (CTF)\n"));
-       LOG_INFO(_("^3fckills^7                  Number of flag carrier kills\n"));
-       LOG_INFO(_("^3returns^7                  Number of flag returns\n"));
-       LOG_INFO(_("^3drops^7                    Number of flag drops\n"));
-       LOG_INFO(_("^3lives^7                    Number of lives (LMS)\n"));
-       LOG_INFO(_("^3rank^7                     Player rank\n"));
-       LOG_INFO(_("^3pushes^7                   Number of players pushed into void\n"));
-       LOG_INFO(_("^3destroyed^7                Number of keys destroyed by pushing them into void\n"));
-       LOG_INFO(_("^3kckills^7                  Number of keys carrier kills\n"));
-       LOG_INFO(_("^3losses^7                   Number of times a key was lost\n"));
-       LOG_INFO(_("^3laps^7                     Number of laps finished (race/cts)\n"));
-       LOG_INFO(_("^3time^7                     Total time raced (race/cts)\n"));
-       LOG_INFO(_("^3fastest^7                  Time of fastest lap (race/cts)\n"));
-       LOG_INFO(_("^3ticks^7                    Number of ticks (DOM)\n"));
-       LOG_INFO(_("^3takes^7                    Number of domination points taken (DOM)\n"));
-       LOG_INFO(_("^3bckills^7                  Number of ball carrier kills\n"));
-       LOG_INFO(_("^3bctime^7                   Total amount of time holding the ball in Keepaway\n"));
-       LOG_INFO(_("^3score^7                    Total score\n"));
-       LOG_INFO("\n");
+       LOG_INFO(_("You can modify the scoreboard using the ^2scoreboard_columns_set command."));
+       LOG_INFO(_("^3|---------------------------------------------------------------|"));
+       LOG_INFO(_("Usage:"));
+       LOG_INFO(_("^2scoreboard_columns_set default"));
+       LOG_INFO(_("^2scoreboard_columns_set ^7field1 field2 ..."));
+       LOG_INFO(_("The following field names are recognized (case insensitive):"));
+       LOG_INFO(_("You can use a ^3|^7 to start the right-aligned fields."));
+       LOG_INFO("");
+
+       LOG_INFO(_("^3name^7 or ^3nick^7             Name of a player"));
+       LOG_INFO(_("^3ping^7                     Ping time"));
+       LOG_INFO(_("^3pl^7                       Packet loss"));
+       LOG_INFO(_("^3elo^7                      Player ELO"));
+       LOG_INFO(_("^3kills^7                    Number of kills"));
+       LOG_INFO(_("^3deaths^7                   Number of deaths"));
+       LOG_INFO(_("^3suicides^7                 Number of suicides"));
+       LOG_INFO(_("^3frags^7                    kills - suicides"));
+       LOG_INFO(_("^3kd^7                       The kill-death ratio"));
+       LOG_INFO(_("^3dmg^7                      The total damage done"));
+       LOG_INFO(_("^3dmgtaken^7                 The total damage taken"));
+       LOG_INFO(_("^3sum^7                      frags - deaths"));
+       LOG_INFO(_("^3caps^7                     How often a flag (CTF) or a key (KeyHunt) was captured"));
+       LOG_INFO(_("^3pickups^7                  How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up"));
+       LOG_INFO(_("^3captime^7                  Time of fastest cap (CTF)"));
+       LOG_INFO(_("^3fckills^7                  Number of flag carrier kills"));
+       LOG_INFO(_("^3returns^7                  Number of flag returns"));
+       LOG_INFO(_("^3drops^7                    Number of flag drops"));
+       LOG_INFO(_("^3lives^7                    Number of lives (LMS)"));
+       LOG_INFO(_("^3rank^7                     Player rank"));
+       LOG_INFO(_("^3pushes^7                   Number of players pushed into void"));
+       LOG_INFO(_("^3destroyed^7                Number of keys destroyed by pushing them into void"));
+       LOG_INFO(_("^3kckills^7                  Number of keys carrier kills"));
+       LOG_INFO(_("^3losses^7                   Number of times a key was lost"));
+       LOG_INFO(_("^3laps^7                     Number of laps finished (race/cts)"));
+       LOG_INFO(_("^3time^7                     Total time raced (race/cts)"));
+       LOG_INFO(_("^3fastest^7                  Time of fastest lap (race/cts)"));
+       LOG_INFO(_("^3ticks^7                    Number of ticks (DOM)"));
+       LOG_INFO(_("^3takes^7                    Number of domination points taken (DOM)"));
+       LOG_INFO(_("^3bckills^7                  Number of ball carrier kills"));
+       LOG_INFO(_("^3bctime^7                   Total amount of time holding the ball in Keepaway"));
+       LOG_INFO(_("^3score^7                    Total score"));
+       LOG_INFO("");
 
        LOG_INFO(_("Before a field you can put a + or - sign, then a comma separated list\n"
                "of game types, then a slash, to make the field show up only in these\n"
@@ -347,11 +346,10 @@ void Cmd_Scoreboard_Help()
        LOG_INFO(_("The special game type names 'teams' and 'noteams' can be used to\n"
                "include/exclude ALL teams/noteams game modes.\n\n"));
 
-       LOG_INFO(_("Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4\n"));
-       LOG_INFO(_("will display name, ping and pl aligned to the left, and the fields\n"
+       LOG_INFO(_("Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4"));
+       LOG_INFO(_("will display name, ping and pl aligned to the left, and the fields"
                "right of the vertical bar aligned to the right.\n"));
-       LOG_INFO(_("'field3' will only be shown in CTF, and 'field4' will be shown in all\n"
-               "other gamemodes except DM.\n"));
+       LOG_INFO(_("'field3' will only be shown in CTF, and 'field4' will be shown in all\nother gamemodes except DM.\n"));
 }
 
 // NOTE: adding a gametype with ? to not warn for an optional field
@@ -476,7 +474,7 @@ LABEL(notfound)
                                else
                                {
                                        if(!nocomplain)
-                                               LOG_INFOF("^1Error:^7 Unknown score field: '%s'\n", str);
+                                               LOG_INFOF("^1Error:^7 Unknown score field: '%s'", str);
                                        continue;
                                }
 LABEL(found)
@@ -515,7 +513,7 @@ LABEL(found)
                        sbt_field_title[0] = strzone(TranslateScoresLabel("name"));
                        sbt_field[0] = SP_NAME;
                        ++sbt_num_fields;
-                       LOG_INFO("fixed missing field 'name'\n");
+                       LOG_INFO("fixed missing field 'name'");
 
                        if(!have_separator)
                        {
@@ -530,7 +528,7 @@ LABEL(found)
                                sbt_field[1] = SP_SEPARATOR;
                                sbt_field_size[1] = stringwidth("|", false, hud_fontsize);
                                ++sbt_num_fields;
-                               LOG_INFO("fixed missing field '|'\n");
+                               LOG_INFO("fixed missing field '|'");
                        }
                }
                else if(!have_separator)
@@ -540,7 +538,7 @@ LABEL(found)
                        sbt_field_size[sbt_num_fields] = stringwidth("|", false, hud_fontsize);
                        sbt_field[sbt_num_fields] = SP_SEPARATOR;
                        ++sbt_num_fields;
-                       LOG_INFO("fixed missing field '|'\n");
+                       LOG_INFO("fixed missing field '|'");
                }
                if(!have_secondary)
                {
@@ -549,7 +547,7 @@ LABEL(found)
                        sbt_field_size[sbt_num_fields] = stringwidth(sbt_field_title[sbt_num_fields], false, hud_fontsize);
                        sbt_field[sbt_num_fields] = ps_secondary;
                        ++sbt_num_fields;
-                       LOG_INFOF("fixed missing field '%s'\n", scores_label(ps_secondary));
+                       LOG_INFOF("fixed missing field '%s'", scores_label(ps_secondary));
                }
                if(!have_primary)
                {
@@ -558,7 +556,7 @@ LABEL(found)
                        sbt_field_size[sbt_num_fields] = stringwidth(sbt_field_title[sbt_num_fields], false, hud_fontsize);
                        sbt_field[sbt_num_fields] = ps_primary;
                        ++sbt_num_fields;
-                       LOG_INFOF("fixed missing field '%s'\n", scores_label(ps_primary));
+                       LOG_INFOF("fixed missing field '%s'", scores_label(ps_primary));
                }
        }
 
index 750e62e..15e18e8 100644 (file)
@@ -24,7 +24,7 @@ void HUD_Vote()
                {
                        vote_yescount = 0;
                        vote_nocount = 0;
-                       LOG_INFO(_("^1You must answer before entering hud configure mode\n"));
+                       LOG_INFO(_("^1You must answer before entering hud configure mode"));
                        cvar_set("_hud_configure", "0");
                }
                if(vote_called_vote)
index 323ebb3..ae624ef 100644 (file)
@@ -97,7 +97,7 @@ void CSQC_Init()
        prvm_language = strzone(cvar_string("prvm_language"));
 
 #ifdef WATERMARK
-       LOG_INFOF("^4CSQC Build information: ^1%s\n", WATERMARK);
+       LOG_INFOF("^4CSQC Build information: ^1%s", WATERMARK);
 #endif
 
        {
@@ -108,6 +108,11 @@ void CSQC_Init()
                maxclients = i;
        }
 
+       // needs to be done so early because of the constants they create
+       static_init();
+       static_init_late();
+       static_init_precache();
+
        binddb = db_create();
        tempdb = db_create();
        ClientProgsDB = db_load("client.db");
@@ -147,6 +152,9 @@ void CSQC_Init()
 
        GetTeam(NUM_SPECTATOR, true); // add specs first
 
+       for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
+               weapon_accuracy[w] = -1;
+
        // precaches
 
        if(autocvar_cl_reticle)
@@ -406,7 +414,7 @@ NET_HANDLE(ENT_CLIENT_SCORES, bool isnew)
        if(!isNew && n != this.sv_entnum)
        {
                //print("A CSQC entity changed its owner!\n");
-               LOG_INFOF("A CSQC entity changed its owner! (edict: %d, classname: %s)\n", etof(this), this.classname);
+               LOG_INFOF("A CSQC entity changed its owner! (edict: %d, classname: %s)", etof(this), this.classname);
                isNew = true;
                Ent_Remove(this);
        }
@@ -488,9 +496,9 @@ NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew)
 
     int f = ReadByte();
 
-       scoreboard_showscores_force = (f & 1);
+       scoreboard_showscores_force = (f & BIT(0));
 
-       if(f & 2)
+       if(f & BIT(1))
        {
                newspectatee_status = ReadByte();
                if(newspectatee_status == player_localnum + 1)
@@ -499,9 +507,9 @@ NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew)
        else
                newspectatee_status = 0;
 
-       spectatorbutton_zoom = (f & 4);
+       spectatorbutton_zoom = (f & BIT(2));
 
-       if(f & 16)
+       if(f & BIT(4))
        {
                num_spectators = ReadByte();
 
@@ -818,7 +826,7 @@ void CSQC_Ent_Update(entity this, bool isnew)
        {
                if (t != this.enttype || isnew)
                {
-                       LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", etof(this), this.entnum, this.enttype, t);
+                       LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)", etof(this), this.entnum, this.enttype, t);
                        Ent_Remove(this);
                        clearentity(this);
                        isnew = true;
@@ -828,7 +836,7 @@ void CSQC_Ent_Update(entity this, bool isnew)
        {
                if (!isnew)
                {
-                       LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", etof(this), this.entnum, t);
+                       LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)", etof(this), this.entnum, t);
                        isnew = true;
                }
        }
@@ -838,7 +846,7 @@ void CSQC_Ent_Update(entity this, bool isnew)
        FOREACH(LinkedEntities, it.m_id == t, {
                if (isnew) this.classname = it.netname;
                if (autocvar_developer_csqcentities)
-            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);
+            LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
                done = it.m_read(this, NULL, isnew);
                MUTATOR_CALLHOOK(Ent_Update, this, isnew);
                break;
@@ -878,7 +886,7 @@ void Ent_Remove(entity this)
 // CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed.  Essentially call remove(this) as well.
 void CSQC_Ent_Remove(entity this)
 {
-       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}\n", this, this.entnum, this.enttype);
+       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}", this, this.entnum, this.enttype);
        if (wasfreed(this))
        {
                LOG_WARN("CSQC_Ent_Remove called for already removed entity. Packet loss?");
@@ -900,20 +908,20 @@ void Gamemode_Init()
 // CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided.  To execute standard behavior, simply execute localcmd with the string.
 void CSQC_Parse_StuffCmd(string strMessage)
 {
-       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_StuffCmd(\"%s\")\n", strMessage);
+       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_StuffCmd(\"%s\")", strMessage);
        localcmd(strMessage);
 }
 // CSQC_Parse_Print : Provides the print string in the first parameter that the server provided.  To execute standard behavior, simply execute print with the string.
 void CSQC_Parse_Print(string strMessage)
 {
-       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_Print(\"%s\")\n", strMessage);
+       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_Print(\"%s\")", strMessage);
        print(ColorTranslateRGB(strMessage));
 }
 
 // CSQC_Parse_CenterPrint : Provides the centerprint_hud string in the first parameter that the server provided.
 void CSQC_Parse_CenterPrint(string strMessage)
 {
-       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_CenterPrint(\"%s\")\n", strMessage);
+       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_CenterPrint(\"%s\")", strMessage);
        centerprint_hud(strMessage);
 }
 
@@ -927,12 +935,12 @@ bool CSQC_Parse_TempEntity()
 
        FOREACH(TempEntities, it.m_id == nTEID, {
                if (autocvar_developer_csqcentities)
-                       LOG_INFOF("CSQC_Parse_TempEntity() nTEID=%s (%d)\n", it.netname, nTEID);
+                       LOG_INFOF("CSQC_Parse_TempEntity() nTEID=%s (%d)", it.netname, nTEID);
                return it.m_read(NULL, NULL, true);
        });
 
        if (autocvar_developer_csqcentities)
-               LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID);
+               LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d", nTEID);
 
        // No special logic for this temporary entity; return 0 so the engine can handle it
        return false;
index 9e783d3..b34bd0f 100644 (file)
@@ -497,7 +497,7 @@ void Cmd_MapVote_MapDownload(int argc)
 
        if(argc != 2 || !mv_pk3list)
        {
-               LOG_INFO(_("mv_mapdownload: ^3You're not supposed to use this command on your own!\n"));
+               LOG_INFO(_("mv_mapdownload: ^3You're not supposed to use this command on your own!"));
                return;
        }
 
@@ -507,7 +507,7 @@ void Cmd_MapVote_MapDownload(int argc)
                        break;
 
        if(!pak || pak.sv_entnum != id) {
-               LOG_INFO(_("^1Error:^7 Couldn't find pak index.\n"));
+               LOG_INFO(_("^1Error:^7 Couldn't find pak index."));
                return;
        }
 
@@ -516,7 +516,7 @@ void Cmd_MapVote_MapDownload(int argc)
                mv_preview[id] = true;
                return;
        } else {
-               LOG_INFO(_("Requesting preview...\n"));
+               LOG_INFO(_("Requesting preview..."));
                localcmd(strcat("\ncmd mv_getpicture ", ftos(id), "\n"));
        }
 }
index 84a475a..fd1647d 100644 (file)
@@ -569,7 +569,7 @@ void URI_Get_Callback(int id, int status, string data)
        }
        else
        {
-               LOG_INFOF("Received HTTP request data for an invalid id %d.\n", id);
+               LOG_INFOF("Received HTTP request data for an invalid id %d.", id);
        }
 }
 
@@ -584,7 +584,7 @@ void Accuracy_LoadLevels()
                if(acc_levels > MAX_ACCURACY_LEVELS)
                        acc_levels = MAX_ACCURACY_LEVELS;
                if(acc_levels < 2)
-                       LOG_INFO("Warning: accuracy_color_levels must contain at least 2 values\n");
+                       LOG_INFO("Warning: accuracy_color_levels must contain at least 2 values");
 
                int i;
                for(i = 0; i < acc_levels; ++i)
index 0cf3b30..e2aadf1 100644 (file)
@@ -1808,7 +1808,7 @@ void CSQC_UpdateView(entity this, float w, float h)
                ov_enabled = true;
 
                #if 0
-               LOG_INFOF("OrthoView: org = %s, angles = %s, distance = %f, nearest = %f, furthest = %f\n",
+               LOG_INFOF("OrthoView: org = %s, angles = %s, distance = %f, nearest = %f, furthest = %f",
                        vtos(ov_org),
                        vtos(getpropertyvec(VF_ANGLES)),
                        ov_distance,
index a9abd98..c58a3df 100644 (file)
@@ -86,12 +86,12 @@ void GenericCommand_addtolist(float request, float argc)
                }
 
                default:
-                       LOG_INFO("Incorrect parameters for ^2addtolist^7\n");
+                       LOG_INFO("Incorrect parameters for ^2addtolist^7");
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " addtolist variable value\n"));
-                       LOG_INFO("  Where 'variable' is what to add 'value' to.\n");
-                       LOG_INFO("See also: ^2removefromlist^7\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " addtolist variable value");
+                       LOG_INFO("  Where 'variable' is what to add 'value' to.");
+                       LOG_INFO("See also: ^2removefromlist^7");
                        return;
                }
        }
@@ -153,7 +153,7 @@ void GenericCommand_qc_curl(float request, float argc)
                                curl_uri_get_pos = (curl_uri_get_pos + 1) % (URI_GET_CURL_END - URI_GET_CURL + 1);
                        }
                        else
-                               LOG_INFO(_("error creating curl handle\n"));
+                               LOG_INFO(_("error creating curl handle"));
 
                        buf_del(buf);
 
@@ -163,7 +163,7 @@ void GenericCommand_qc_curl(float request, float argc)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " qc_curl [--key N] [--cvar] [--exec] URL [postargs...]"));
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " qc_curl [--key N] [--cvar] [--exec] URL [postargs...]");
                        return;
                }
        }
@@ -203,13 +203,13 @@ GENERIC_COMMAND(dumpcommands, "Dump all commands on the program to *_cmd_dump.tx
                                CMD_Write("\ndump of generic commands:\n");
                                GenericCommand_macro_write_aliases(fh);
 
-                               LOG_INFO("Completed dump of aliases in ^2data/data/", GetProgramCommandPrefix(), "_dump.txt^7.\n");
+                               LOG_INFO("Completed dump of aliases in ^2data/data/", GetProgramCommandPrefix(), "_dump.txt^7.");
 
                                fclose(fh);
                        }
                        else
                        {
-                               LOG_INFO("^1Error: ^7Could not dump to file!\n");
+                               LOG_INFO("^1Error: ^7Could not dump to file!");
                        }
                        return;
                }
@@ -217,8 +217,8 @@ GENERIC_COMMAND(dumpcommands, "Dump all commands on the program to *_cmd_dump.tx
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpcommands"));
-                       LOG_INFO("  No arguments required.\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " dumpcommands");
+                       LOG_INFO("  No arguments required.");
                        return;
                }
        }
@@ -241,7 +241,7 @@ void GenericCommand_maplist(float request, float argc)
                                        {
                                                if (!fexists(strcat("maps/", argv(2), ".bsp")))
                                                {
-                                                       LOG_INFO("maplist: ERROR: ", argv(2), " does not exist!\n");
+                                                       LOG_INFO("maplist: ERROR: ", argv(2), " does not exist!");
                                                        break;
                                                }
 
@@ -295,13 +295,13 @@ void GenericCommand_maplist(float request, float argc)
                }
 
                default:
-                       LOG_INFO("Incorrect parameters for ^2maplist^7\n");
+                       LOG_INFO("Incorrect parameters for ^2maplist^7");
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " maplist action [map]\n"));
-                       LOG_INFO("  Where 'action' is the command to complete,\n");
-                       LOG_INFO("  and 'map' is what it acts upon (if required).\n");
-                       LOG_INFO("  Full list of commands here: \"add, cleanup, remove, shuffle.\"\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " maplist action [map]");
+                       LOG_INFO("  Where 'action' is the command to complete,");
+                       LOG_INFO("  and 'map' is what it acts upon (if required).");
+                       LOG_INFO("  Full list of commands here: \"add, cleanup, remove, shuffle.\"");
                        return;
                }
        }
@@ -320,8 +320,8 @@ void GenericCommand_nextframe(float request, float arguments, string command)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " nextframe command...\n"));
-                       LOG_INFO("  Where command will be executed next frame of this VM\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " nextframe command...");
+                       LOG_INFO("  Where command will be executed next frame of this VM");
                        return;
                }
        }
@@ -351,12 +351,12 @@ void GenericCommand_removefromlist(float request, float argc)
                }
 
                default:
-                       LOG_INFO("Incorrect parameters for ^2removefromlist^7\n");
+                       LOG_INFO("Incorrect parameters for ^2removefromlist^7");
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " removefromlist variable value\n"));
-                       LOG_INFO("  Where 'variable' is what cvar to remove 'value' from.\n");
-                       LOG_INFO("See also: ^2addtolist^7\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " removefromlist variable value");
+                       LOG_INFO("  Where 'variable' is what cvar to remove 'value' from.");
+                       LOG_INFO("See also: ^2addtolist^7");
                        return;
                }
        }
@@ -375,10 +375,10 @@ void GenericCommand_restartnotifs(float request)
                        int NOTIF_MULTI_COUNT   = 0; FOREACH(Notifications, it.nent_type == MSG_MULTI,   { ++NOTIF_MULTI_COUNT;  });
                        int NOTIF_CHOICE_COUNT  = 0; FOREACH(Notifications, it.nent_type == MSG_CHOICE,  { ++NOTIF_CHOICE_COUNT; });
                        LOG_INFOF(
-                               strcat(
-                                       "Restart_Notifications(): Restarting %d notifications... ",
-                                       "Counts: MSG_ANNCE = %d, MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d, MSG_CHOICE = %d\n"
-                               ),
+                           (
+                    "Restart_Notifications(): Restarting %d notifications... "
+                    "Counts: MSG_ANNCE = %d, MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d, MSG_CHOICE = %d"
+                ),
                                (
                                        NOTIF_ANNCE_COUNT +
                                        NOTIF_INFO_COUNT +
@@ -395,7 +395,7 @@ void GenericCommand_restartnotifs(float request)
                        Destroy_All_Notifications();
                        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
                        #else
-                       LOG_INFO(_("Notification restart command only works with cl_cmd and sv_cmd.\n"));
+                       LOG_INFO(_("Notification restart command only works with cl_cmd and sv_cmd."));
                        #endif
                        return;
                }
@@ -403,8 +403,8 @@ void GenericCommand_restartnotifs(float request)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " restartnotifs"));
-                       LOG_INFO("  No arguments required.\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " restartnotifs");
+                       LOG_INFO("  No arguments required.");
                        return;
                }
        }
@@ -430,12 +430,12 @@ void GenericCommand_settemp(float request, float argc)
                }
 
                default:
-                       LOG_INFO("Incorrect parameters for ^2settemp^7\n");
+                       LOG_INFO("Incorrect parameters for ^2settemp^7");
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " settemp \"cvar\" \"arguments\"\n"));
-                       LOG_INFO("  Where 'cvar' is the cvar you want to temporarily set with 'arguments'.\n");
-                       LOG_INFO("See also: ^2settemp_restore^7\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " settemp \"cvar\" \"arguments\"");
+                       LOG_INFO("  Where 'cvar' is the cvar you want to temporarily set with 'arguments'.");
+                       LOG_INFO("See also: ^2settemp_restore^7");
                        return;
                }
        }
@@ -460,9 +460,9 @@ void GenericCommand_settemp_restore(float request, float argc)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " settemp_restore\n"));
-                       LOG_INFO("  No arguments required.\n");
-                       LOG_INFO("See also: ^2settemp^7\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " settemp_restore");
+                       LOG_INFO("  No arguments required.");
+                       LOG_INFO("See also: ^2settemp^7");
                        return;
                }
        }
@@ -488,7 +488,7 @@ void GenericCommand_runtest(float request, float argc)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " [function to run]"));
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " [function to run]");
                        return;
                }
        }
@@ -531,7 +531,7 @@ GENERIC_COMMAND(runtest, "Run unit tests") { GenericCommand_runtest(request, arg
 
 void GenericCommand_macro_help()
 {
-       FOREACH(GENERIC_COMMANDS, true, LOG_INFOF("  ^2%s^7: %s\n", it.m_name, it.m_description));
+       FOREACH(GENERIC_COMMANDS, true, LOG_INFOF("  ^2%s^7: %s", it.m_name, it.m_description));
 }
 
 float GenericCommand_macro_command(float argc, string command)
index 828fbdf..7e1c4f5 100644 (file)
@@ -13,7 +13,7 @@ string rpn_pop()
                --rpn_sp;
                return rpn_stack[rpn_sp];
        } else {
-               LOG_INFO("rpn: stack underflow\n");
+               LOG_INFO("rpn: stack underflow");
                rpn_error = true;
                return "";
        }
@@ -24,7 +24,7 @@ void rpn_push(string s)
                rpn_stack[rpn_sp] = s;
                ++rpn_sp;
        } else {
-               LOG_INFO("rpn: stack overflow\n");
+               LOG_INFO("rpn: stack overflow");
                rpn_error = true;
        }
 }
@@ -33,7 +33,7 @@ string rpn_get()
        if(rpn_sp > 0) {
                return rpn_stack[rpn_sp - 1];
        } else {
-               LOG_INFO("rpn: empty stack\n");
+               LOG_INFO("rpn: empty stack");
                rpn_error = true;
                return "";
        }
@@ -43,7 +43,7 @@ void rpn_set(string s)
        if(rpn_sp > 0) {
                rpn_stack[rpn_sp - 1] = s;
        } else {
-               LOG_INFO("rpn: empty stack\n");
+               LOG_INFO("rpn: empty stack");
                rpn_error = true;
        }
 }
@@ -107,7 +107,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                }
                                                else
                                                {
-                                                       LOG_INFO("rpn: empty cvar name for 'def'\n");
+                                                       LOG_INFO("rpn: empty cvar name for 'def'");
                                                        rpn_error = true;
                                                }
                                        } else if(rpncmd == "defs" || rpncmd == "@") {
@@ -132,7 +132,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                }
                                                else
                                                {
-                                                       LOG_INFO("rpn: empty cvar name for 'defs'\n");
+                                                       LOG_INFO("rpn: empty cvar name for 'defs'");
                                                        rpn_error = true;
                                                }
                                        } else if(rpncmd == "load") {
@@ -288,7 +288,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                                db_put(rpn_db, "stack.pos", ftos(i-2));
                                                } else {
                                                        rpn_error = 1;
-                                                       LOG_INFO("rpn: database underflow\n");
+                                                       LOG_INFO("rpn: database underflow");
                                                }
                                        } else if(rpncmd == "dbget") {
 
@@ -298,7 +298,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                        rpn_push(db_get(rpn_db, strcat("stack.", ftos(i-1))));
                                                } else {
                                                        rpn_error = 1;
-                                                       LOG_INFO("rpn: database empty\n");
+                                                       LOG_INFO("rpn: database empty");
                                                }
                                        } else if(rpncmd == "dblen") {
                                                rpn_push(db_get(rpn_db, "stack.pointer"));
@@ -347,7 +347,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                if(!j)
                                                {
                                                        rpn_error = true;
-                                                       LOG_INFO("rpn: empty database\n");
+                                                       LOG_INFO("rpn: empty database");
                                                } else {
                                                        --j;
                                                        rpn_push(db_get(rpn_db, strcat("stack.", ftos(i))));
@@ -372,7 +372,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                        rpn_push(db_get(rpn_db, strcat("stack.", s)));
                                                } else {
                                                        rpn_error = 1;
-                                                       LOG_INFO("rpn: empty database\n");
+                                                       LOG_INFO("rpn: empty database");
                                                }
                                        } else if(rpncmd == "dbat") {
                                                rpn_push(db_get(rpn_db, "stack.pos"));
@@ -384,7 +384,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                {
                                                        if(i < 0 || i >= j)
                                                        {
-                                                               LOG_INFO("rpn: database cursor out of bounds\n");
+                                                               LOG_INFO("rpn: database cursor out of bounds");
                                                                rpn_error = true;
                                                        }
                                                        if(!rpn_error)
@@ -398,7 +398,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                if(!j)
                                                {
                                                        rpn_error = true;
-                                                       LOG_INFO("rpn: empty database, cannot move cursor\n");
+                                                       LOG_INFO("rpn: empty database, cannot move cursor");
                                                }
                                                if(!rpn_error)
                                                {
@@ -412,7 +412,7 @@ void GenericCommand_rpn(float request, float argc, string command)
                                                        j = stof(db_get(rpn_db, "stack.pointer"));
                                                        if(i < 0 || i >= j)
                                                        {
-                                                               LOG_INFO("rpn: database cursor destination out of bounds\n");
+                                                               LOG_INFO("rpn: database cursor destination out of bounds");
                                                                rpn_error = true;
                                                        }
                                                        if(!rpn_error)
@@ -514,7 +514,7 @@ LABEL(skip_difference)
                                                {
                                                        if (!fexists(s))
                                                        {
-                                                               LOG_INFO("rpn: ERROR: ", s, " does not exist!\n");
+                                                               LOG_INFO("rpn: ERROR: ", s, " does not exist!");
                                                                rpn_error = true;
                                                        }
                                                }
@@ -553,7 +553,7 @@ LABEL(skip_difference)
                                while(rpn_sp > 0)
                                {
                                        s = rpn_pop();
-                                       LOG_INFO("rpn: still on stack: ", s, "\n");
+                                       LOG_INFO("rpn: still on stack: ", s);
                                }
                        }
 
@@ -563,42 +563,42 @@ LABEL(skip_difference)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " rpn EXPRESSION...\n"));
-                       LOG_INFO("    Operator description (x: string, s: set, f: float):\n");
-                       LOG_INFO("    x pop ----------------------------->     : removes the top\n");
-                       LOG_INFO("    x dup -----------------------------> x x : duplicates the top\n");
-                       LOG_INFO("    x x exch --------------------------> x x : swap the top two\n");
-                       LOG_INFO("    /cvarname load --------------------> x   : loads a cvar\n");
-                       LOG_INFO("    /cvarname x def ------------------->     : writes to a cvar\n");
-                       LOG_INFO("    f f add|sub|mul|div|mod|pow -------> f   : adds/... two numbers\n");
-                       LOG_INFO("    f f and|or|xor|bitand|bitor|bitxor > f   : logical and bitwise operations\n");
-                       LOG_INFO("    f f eq|ne|gt|ge|lt|le|max|min -----> f   : compares two numbers\n");
-                       LOG_INFO("    f neg|abs|sgn|rand|floor|ceil------> f   : negates/... a number\n");
-                       LOG_INFO("    f not|bitnot ----------------------> f   : logical and bitwise negation\n");
-                       LOG_INFO("    f exp|log|sin|cos -----------------> f   : exponential function & Co.\n");
-                       LOG_INFO("    f f f bound -----------------------> f   : bounds the middle number\n");
-                       LOG_INFO("    f1 f2 b when ----------------------> f   : f1 if b, f2 otherwise\n");
-                       LOG_INFO("    s s union|intersection|difference -> s   : set operations\n");
-                       LOG_INFO("    s shuffle -------------------------> s   : randomly arrange elements\n");
-                       LOG_INFO("    /key /value put ------------------->     : set a database key\n");
-                       LOG_INFO("    /key get --------------------------> s   : get a database value\n");
-                       LOG_INFO("    x dbpush -------------------------->     : pushes the top onto the database\n");
-                       LOG_INFO("    dbpop|dbget -----------------------> x   : removes/reads DB's top\n");
-                       LOG_INFO("    dblen|dbat ------------------------> f   : gets the DB's size/cursor pos\n");
-                       LOG_INFO("    dbclr ----------------------------->     : clear the DB\n");
-                       LOG_INFO("    s dbsave|dbload-------------------->     : save/load the DB to/from a file\n");
-                       LOG_INFO("    x dbins --------------------------->     : moves the top into the DB\n");
-                       LOG_INFO("    dbext|dbread ----------------------> x   : extract/get from the DB's cursor\n");
-                       LOG_INFO("    f dbmov|dbgoto -------------------->     : move or set the DB's cursor\n");
-                       LOG_INFO("    s localtime -----------------------> s   : formats the current local time\n");
-                       LOG_INFO("    s gmtime --------------------------> s   : formats the current UTC time\n");
-                       LOG_INFO("    time ------------------------------> f   : seconds since VM start\n");
-                       LOG_INFO("    s /MD4 digest ---------------------> s   : MD4 digest\n");
-                       LOG_INFO("    s /SHA256 digest ------------------> s   : SHA256 digest\n");
-                       LOG_INFO("    s /formatstring sprintf1s ---------> s   : sprintf with 1 string (pad, cut)\n");
-                       LOG_INFO("    s eval ---------------------------->     : does something eval\n");
-                       LOG_INFO("    Set operations operate on 'such''strings'.\n");
-                       LOG_INFO("    Unknown tokens insert their cvar value.\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " rpn EXPRESSION...");
+                       LOG_INFO("    Operator description (x: string, s: set, f: float):");
+                       LOG_INFO("    x pop ----------------------------->     : removes the top");
+                       LOG_INFO("    x dup -----------------------------> x x : duplicates the top");
+                       LOG_INFO("    x x exch --------------------------> x x : swap the top two");
+                       LOG_INFO("    /cvarname load --------------------> x   : loads a cvar");
+                       LOG_INFO("    /cvarname x def ------------------->     : writes to a cvar");
+                       LOG_INFO("    f f add|sub|mul|div|mod|pow -------> f   : adds/... two numbers");
+                       LOG_INFO("    f f and|or|xor|bitand|bitor|bitxor > f   : logical and bitwise operations");
+                       LOG_INFO("    f f eq|ne|gt|ge|lt|le|max|min -----> f   : compares two numbers");
+                       LOG_INFO("    f neg|abs|sgn|rand|floor|ceil------> f   : negates/... a number");
+                       LOG_INFO("    f not|bitnot ----------------------> f   : logical and bitwise negation");
+                       LOG_INFO("    f exp|log|sin|cos -----------------> f   : exponential function & Co.");
+                       LOG_INFO("    f f f bound -----------------------> f   : bounds the middle number");
+                       LOG_INFO("    f1 f2 b when ----------------------> f   : f1 if b, f2 otherwise");
+                       LOG_INFO("    s s union|intersection|difference -> s   : set operations");
+                       LOG_INFO("    s shuffle -------------------------> s   : randomly arrange elements");
+                       LOG_INFO("    /key /value put ------------------->     : set a database key");
+                       LOG_INFO("    /key get --------------------------> s   : get a database value");
+                       LOG_INFO("    x dbpush -------------------------->     : pushes the top onto the database");
+                       LOG_INFO("    dbpop|dbget -----------------------> x   : removes/reads DB's top");
+                       LOG_INFO("    dblen|dbat ------------------------> f   : gets the DB's size/cursor pos");
+                       LOG_INFO("    dbclr ----------------------------->     : clear the DB");
+                       LOG_INFO("    s dbsave|dbload-------------------->     : save/load the DB to/from a file");
+                       LOG_INFO("    x dbins --------------------------->     : moves the top into the DB");
+                       LOG_INFO("    dbext|dbread ----------------------> x   : extract/get from the DB's cursor");
+                       LOG_INFO("    f dbmov|dbgoto -------------------->     : move or set the DB's cursor");
+                       LOG_INFO("    s localtime -----------------------> s   : formats the current local time");
+                       LOG_INFO("    s gmtime --------------------------> s   : formats the current UTC time");
+                       LOG_INFO("    time ------------------------------> f   : seconds since VM start");
+                       LOG_INFO("    s /MD4 digest ---------------------> s   : MD4 digest");
+                       LOG_INFO("    s /SHA256 digest ------------------> s   : SHA256 digest");
+                       LOG_INFO("    s /formatstring sprintf1s ---------> s   : sprintf with 1 string (pad, cut)");
+                       LOG_INFO("    s eval ---------------------------->     : does something eval");
+                       LOG_INFO("    Set operations operate on 'such''strings'.");
+                       LOG_INFO("    Unknown tokens insert their cvar value.");
                        return;
                }
        }
index 28153a7..0200883 100644 (file)
@@ -170,14 +170,14 @@ bool autocvar_debugdraw;
                                        e.debug = true;
                                        --rem;
                                }
-                               LOG_INFOF("%d server entities sent\n", n - rem);
+                               LOG_INFOF("%d server entities sent", n - rem);
                                return;
                        }
 
                        default:
                        case CMD_REQUEST_USAGE:
                        {
-                               LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " debugdraw_sv"));
+                               LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " debugdraw_sv");
                                return;
                        }
                }
@@ -194,14 +194,14 @@ GENERIC_COMMAND(bufstr_get, "Examine a string buffer object")
                        int bufhandle = stof(argv(1));
                        int string_index = stof(argv(2));
                        string s = bufstr_get(bufhandle, string_index);
-                       LOG_INFOF("%s\n", s);
+                       LOG_INFOF("%s", s);
                        return;
                }
 
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " bufstr_get bufhandle string_index"));
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " bufstr_get bufhandle string_index");
                        return;
                }
        }
@@ -213,13 +213,13 @@ GENERIC_COMMAND(version, "Print the current version")
        {
                case CMD_REQUEST_COMMAND:
                {
-                       LOG_INFO(WATERMARK "\n");
+                       LOG_INFO(WATERMARK);
                        return;
                }
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " version"));
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " version");
                        return;
                }
        }
@@ -253,7 +253,7 @@ GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars")
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " cvar_localchanges"));
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " cvar_localchanges");
                        return;
                }
        }
@@ -326,22 +326,22 @@ GENERIC_COMMAND(find, "Search through entities for matching classname")
                        int entcnt = 0;
                        FOREACH_ENTITY_CLASS_ORDERED(argv(1), true,
                        {
-                               LOG_INFOF("%i (%s)\n", it, it.classname);
+                               LOG_INFOF("%i (%s)", it, it.classname);
                                ++entcnt;
                        });
                        if(entcnt)
-                               LOG_INFOF("Found %d entities\n", entcnt);
+                               LOG_INFOF("Found %d entities", entcnt);
                        return;
                }
 
                default:
                {
-                       LOG_INFO("Incorrect parameters for ^2find^7\n");
+                       LOG_INFO("Incorrect parameters for ^2find^7");
         }
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 " GetProgramCommandPrefix() " find classname\n");
-                       LOG_INFO("  Where 'classname' is the classname to search for.\n");
+                       LOG_INFO("Usage:^3 " GetProgramCommandPrefix() " find classname");
+                       LOG_INFO("  Where 'classname' is the classname to search for.");
                        return;
                }
        }
@@ -354,15 +354,15 @@ GENERIC_COMMAND(findat, "Search through entities for matching origin")
                case CMD_REQUEST_COMMAND:
                {
                    vector match = stov(argv(1));
-                   FOREACH_ENTITY_ORDERED(it.origin == match, LOG_INFOF("%i (%s)\n", it, it.classname));
+                   FOREACH_ENTITY_ORDERED(it.origin == match, LOG_INFOF("%i (%s)", it, it.classname));
                        return;
                }
 
                default:
-                       LOG_INFO("Incorrect parameters for ^2findat^7\n");
+                       LOG_INFO("Incorrect parameters for ^2findat^7");
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 " GetProgramCommandPrefix() " findat \"0 0 0\"\n");
+                       LOG_INFO("Usage:^3 " GetProgramCommandPrefix() " findat \"0 0 0\"");
                        return;
                }
        }
index f662aee..71260eb 100644 (file)
@@ -303,8 +303,8 @@ GENERIC_COMMAND(dumpeffectinfo, "Dump all effectinfo to effectinfo_dump.txt")
             int fh = fopen(filename, FILE_WRITE);
             if (fh >= 0) {
                effectinfo_dump(fh, alsoprint);
-                LOG_INFOF("Dumping effectinfo... File located at ^2data/data/%s^7.\n", filename);
-                               LOG_INFOF("Reload with ^2cl_particles_reloadeffects data/%s^7.\n", filename);
+                LOG_INFOF("Dumping effectinfo... File located at ^2data/data/%s^7.", filename);
+                               LOG_INFOF("Reload with ^2cl_particles_reloadeffects data/%s^7.", filename);
                 fclose(fh);
             } else {
                 LOG_WARNF("Could not open file '%s'!", filename);
@@ -313,10 +313,10 @@ GENERIC_COMMAND(dumpeffectinfo, "Dump all effectinfo to effectinfo_dump.txt")
         }
         default:
         case CMD_REQUEST_USAGE: {
-            LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpeffectinfo [filename]"));
-            LOG_INFO("  Where 'filename' is the file to write (default is effectinfo_dump.txt),\n");
-            LOG_INFO("  if supplied with '-' output to console as well as default,\n");
-            LOG_INFO("  if left blank, it will only write to default.\n");
+            LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " dumpeffectinfo [filename]");
+            LOG_INFO("  Where 'filename' is the file to write (default is effectinfo_dump.txt),");
+            LOG_INFO("  if supplied with '-' output to console as well as default,");
+            LOG_INFO("  if left blank, it will only write to default.");
             return;
         }
     }
index c3cec69..90cfa6a 100644 (file)
@@ -1,3 +1,7 @@
 // generated file; do not modify
+#include <common/gamemodes/rules.qc>
+#ifdef SVQC
+    #include <common/gamemodes/sv_rules.qc>
+#endif
 
 #include <common/gamemodes/gamemode/_mod.inc>
index 685c277..b3ed42d 100644 (file)
@@ -1,3 +1,7 @@
 // generated file; do not modify
+#include <common/gamemodes/rules.qh>
+#ifdef SVQC
+    #include <common/gamemodes/sv_rules.qh>
+#endif
 
 #include <common/gamemodes/gamemode/_mod.qh>
index f48ef74..7872767 100644 (file)
@@ -1,3 +1,6 @@
 // generated file; do not modify
 #include <common/gamemodes/gamemode/nexball/nexball.qc>
 #include <common/gamemodes/gamemode/nexball/weapon.qc>
+#ifdef SVQC
+    #include <common/gamemodes/gamemode/nexball/sv_weapon.qc>
+#endif
index 4ac2347..a1cf544 100644 (file)
@@ -1,3 +1,6 @@
 // generated file; do not modify
 #include <common/gamemodes/gamemode/nexball/nexball.qh>
 #include <common/gamemodes/gamemode/nexball/weapon.qh>
+#ifdef SVQC
+    #include <common/gamemodes/gamemode/nexball/sv_weapon.qh>
+#endif
index ba42962..5a0ff2a 100644 (file)
@@ -15,6 +15,8 @@ MUTATOR_HOOKFUNCTION(cl_nb, WantEventchase)
 #ifdef SVQC
 .float metertime = _STAT(NB_METERSTART);
 
+.entity ballcarried;
+
 int autocvar_g_nexball_goalleadlimit;
 #define autocvar_g_nexball_goallimit cvar("g_nexball_goallimit")
 
@@ -69,14 +71,14 @@ float OtherTeam(float t)  //works only if there are two teams on the map!
        return e.team;
 }
 
-const float ST_NEXBALL_GOALS = 1;
+const int ST_NEXBALL_GOALS = 1;
 void nb_ScoreRules(int teams)
 {
-       ScoreRules_basics(teams, 0, 0, true);
-       ScoreInfo_SetLabel_TeamScore(   ST_NEXBALL_GOALS,  "goals", SFL_SORT_PRIO_PRIMARY);
-       ScoreInfo_SetLabel_PlayerScore( SP_NEXBALL_GOALS,  "goals", SFL_SORT_PRIO_PRIMARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_NEXBALL_FAULTS, "faults", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER);
-       ScoreRules_basics_end();
+    GameRules_scoring(teams, 0, 0, {
+        field_team(ST_NEXBALL_GOALS, "goals", SFL_SORT_PRIO_PRIMARY);
+        field(SP_NEXBALL_GOALS, "goals", SFL_SORT_PRIO_PRIMARY);
+        field(SP_NEXBALL_FAULTS, "faults", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER);
+    });
 }
 
 void LogNB(string mode, entity actor)
@@ -119,14 +121,16 @@ void relocate_nexball(entity this)
        tracebox(this.origin, BALL_MINS, BALL_MAXS, this.origin, true, this);
        if(trace_startsolid)
        {
-               vector o;
-               o = this.origin;
-               if(!move_out_of_solid(this))
+               vector o = this.origin;
+               if (!move_out_of_solid(this)) {
                        objerror(this, "could not get out of solid at all!");
-               LOG_INFO("^1NOTE: this map needs FIXING. ", this.classname, " at ", vtos(o - '0 0 1'));
-               LOG_INFO(" needs to be moved out of solid, e.g. by '", ftos(this.origin.x - o.x));
-               LOG_INFO(" ", ftos(this.origin.y - o.y));
-               LOG_INFO(" ", ftos(this.origin.z - o.z), "'\n");
+        }
+        LOG_INFOF(
+            "^1NOTE: this map needs FIXING. %s at %s needs to be moved out of solid, e.g. by %s",
+            this.classname,
+            vtos(o - '0 0 1'),
+            vtos(this.origin - o)
+        );
                this.origin = o;
        }
 }
@@ -149,6 +153,7 @@ void GiveBall(entity plyr, entity ball)
        {
                ownr.effects &= ~autocvar_g_nexball_basketball_effects_default;
                ownr.ballcarried = NULL;
+               GameRules_scoring_vip(ownr, false);
                if(ownr.metertime)
                {
                        ownr.metertime = 0;
@@ -171,6 +176,7 @@ void GiveBall(entity plyr, entity ball)
        ball.weaponentity_fld = weaponentity;
        ball.team = plyr.team;
        plyr.ballcarried = ball;
+       GameRules_scoring_vip(plyr, true);
        ball.nb_dropper = plyr;
 
        plyr.effects |= autocvar_g_nexball_basketball_effects_default;
@@ -228,8 +234,9 @@ void DropBall(entity ball, vector org, vector vel)
        WaypointSprite_Spawn(WP_NbBall, 0, 0, ball, '0 0 64', NULL, ball.team, ball, waypointsprite_attachedforcarrier, false, RADARICON_FLAGCARRIER); // no health bar please
        WaypointSprite_UpdateRule(ball.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
 
-       ball.owner.ballcarried = NULL;
-       ball.owner = NULL;
+       entity e = ball.owner; ball.owner = NULL;
+       e.ballcarried = NULL;
+       GameRules_scoring_vip(e, false);
 }
 
 void InitBall(entity this)
@@ -428,9 +435,9 @@ void GoalTouch(entity this, entity toucher)
        if(isclient)
        {
                if(pscore > 0)
-                       PlayerScore_Add(ball.pusher, SP_NEXBALL_GOALS, pscore);
+                       GameRules_scoring_add(ball.pusher, NEXBALL_GOALS, pscore);
                else if(pscore < 0)
-                       PlayerScore_Add(ball.pusher, SP_NEXBALL_FAULTS, -pscore);
+                       GameRules_scoring_add(ball.pusher, NEXBALL_FAULTS, -pscore);
        }
 
        if(ball.owner)  // Happens on spawnflag GOAL_TOUCHPLAYER
@@ -715,136 +722,6 @@ spawnfunc(ball_bound)
        spawnfunc_nexball_out(this);
 }
 
-//=======================//
-//       Weapon code     //
-//=======================//
-
-
-void W_Nexball_Think(entity this)
-{
-       //dprint("W_Nexball_Think\n");
-       //vector new_dir = steerlib_arrive(this.enemy.origin, 2500);
-       vector new_dir = normalize(this.enemy.origin + '0 0 50' - this.origin);
-       vector old_dir = normalize(this.velocity);
-       float _speed = vlen(this.velocity);
-       vector new_vel = normalize(old_dir + (new_dir * autocvar_g_nexball_safepass_turnrate)) * _speed;
-       //vector new_vel = (new_dir * autocvar_g_nexball_safepass_turnrate
-
-       this.velocity = new_vel;
-
-       this.nextthink = time;
-}
-
-void W_Nexball_Touch(entity this, entity toucher)
-{
-       entity ball, attacker;
-       attacker = this.owner;
-       //this.think = func_null;
-       //this.enemy = NULL;
-
-       PROJECTILE_TOUCH(this, toucher);
-       if(attacker.team != toucher.team || autocvar_g_nexball_basketball_teamsteal)
-               if((ball = toucher.ballcarried) && !STAT(FROZEN, toucher) && !IS_DEAD(toucher) && (IS_PLAYER(attacker)))
-               {
-                       toucher.velocity = toucher.velocity + normalize(this.velocity) * toucher.damageforcescale * autocvar_g_balance_nexball_secondary_force;
-                       UNSET_ONGROUND(toucher);
-                       if(!attacker.ballcarried)
-                       {
-                               LogNB("stole", attacker);
-                               _sound(toucher, CH_TRIGGER, ball.noise2, VOL_BASE, ATTEN_NORM);
-
-                               if(SAME_TEAM(attacker, toucher) && time > CS(attacker).teamkill_complain)
-                               {
-                                       CS(attacker).teamkill_complain = time + 5;
-                                       CS(attacker).teamkill_soundtime = time + 0.4;
-                                       CS(attacker).teamkill_soundsource = toucher;
-                               }
-
-                               GiveBall(attacker, toucher.ballcarried);
-                       }
-               }
-       delete(this);
-}
-
-void W_Nexball_Attack(entity actor, .entity weaponentity, float t)
-{
-       entity ball;
-       float mul, mi, ma;
-       if(!(ball = actor.ballcarried))
-               return;
-
-       W_SetupShot(actor, weaponentity, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0);
-       tracebox(w_shotorg, BALL_MINS, BALL_MAXS, w_shotorg, MOVE_WORLDONLY, NULL);
-       if(trace_startsolid)
-       {
-               if(actor.metertime)
-                       actor.metertime = 0; // Shot failed, hide the power meter
-               return;
-       }
-
-       //Calculate multiplier
-       if(t < 0)
-               mul = 1;
-       else
-       {
-               mi = autocvar_g_nexball_basketball_meter_minpower;
-               ma = max(mi, autocvar_g_nexball_basketball_meter_maxpower); // avoid confusion
-               //One triangle wave period with 1 as max
-               mul = 2 * (t % g_nexball_meter_period) / g_nexball_meter_period;
-               if(mul > 1)
-                       mul = 2 - mul;
-               mul = mi + (ma - mi) * mul; // range from the minimal power to the maximal power
-       }
-
-       DropBall(ball, w_shotorg, W_CalculateProjectileVelocity(actor, actor.velocity, w_shotdir * autocvar_g_balance_nexball_primary_speed * mul, false));
-
-
-       //TODO: use the speed_up cvar too ??
-}
-
-vector trigger_push_calculatevelocity(vector org, entity tgt, float ht);
-
-void W_Nexball_Attack2(entity actor, .entity weaponentity)
-{
-       if(actor.ballcarried.enemy)
-       {
-               entity _ball = actor.ballcarried;
-               W_SetupShot(actor, weaponentity, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0);
-               DropBall(_ball, w_shotorg, trigger_push_calculatevelocity(_ball.origin, _ball.enemy, 32));
-               setthink(_ball, W_Nexball_Think);
-               _ball.nextthink = time;
-               return;
-       }
-
-       if(!autocvar_g_nexball_tackling)
-               return;
-
-       W_SetupShot(actor, weaponentity, false, 2, SND_NB_SHOOT2, CH_WEAPON_A, 0);
-       entity missile = new(ballstealer);
-
-       missile.owner = actor;
-
-       set_movetype(missile, MOVETYPE_FLY);
-       PROJECTILE_MAKETRIGGER(missile);
-
-       //setmodel(missile, "models/elaser.mdl");  // precision set below
-       setsize(missile, '0 0 0', '0 0 0');
-       setorigin(missile, w_shotorg);
-
-       W_SetupProjVelocity_Basic(missile, autocvar_g_balance_nexball_secondary_speed, 0);
-       missile.angles = vectoangles(missile.velocity);
-       settouch(missile, W_Nexball_Touch);
-       setthink(missile, SUB_Remove);
-       missile.nextthink = time + autocvar_g_balance_nexball_secondary_lifetime; //FIXME: use a distance instead?
-
-       missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
-       missile.flags = FL_PROJECTILE;
-       IL_PUSH(g_projectiles, missile);
-       IL_PUSH(g_bot_dodge, missile);
-
-       CSQCProjectile(missile, true, PROJECTILE_ELECTRO, true);
-}
-
 bool ball_customize(entity this, entity client)
 {
        if(!this.owner)
@@ -872,61 +749,6 @@ bool ball_customize(entity this, entity client)
        return true;
 }
 
-METHOD(BallStealer, wr_think, void(BallStealer thiswep, entity actor, .entity weaponentity, int fire))
-{
-    TC(BallStealer, thiswep);
-    if(fire & 1)
-        if(weapon_prepareattack(thiswep, actor, weaponentity, false, autocvar_g_balance_nexball_primary_refire))
-            if(autocvar_g_nexball_basketball_meter)
-            {
-                if(actor.ballcarried && !actor.metertime)
-                    actor.metertime = time;
-                else
-                    weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready);
-            }
-            else
-            {
-                W_Nexball_Attack(actor, weaponentity, -1);
-                weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready);
-            }
-    if(fire & 2)
-        if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_nexball_secondary_refire))
-        {
-            W_Nexball_Attack2(actor, weaponentity);
-            weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_nexball_secondary_animtime, w_ready);
-        }
-
-    if(!(fire & 1) && actor.metertime && actor.ballcarried)
-    {
-        W_Nexball_Attack(actor, weaponentity, time - actor.metertime);
-        // DropBall or stealing will set metertime back to 0
-        weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready);
-    }
-}
-
-METHOD(BallStealer, wr_setup, void(BallStealer this, entity actor, .entity weaponentity))
-{
-    TC(BallStealer, this);
-    //weapon_setup(WEP_PORTO.m_id);
-}
-
-METHOD(BallStealer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
-{
-    TC(BallStealer, this);
-}
-
-METHOD(BallStealer, wr_checkammo1, bool(BallStealer this, entity actor, .entity weaponentity))
-{
-    TC(BallStealer, this);
-    return true;
-}
-
-METHOD(BallStealer, wr_checkammo2, bool(BallStealer this, entity actor, .entity weaponentity))
-{
-    TC(BallStealer, this);
-    return true;
-}
-
 void nb_DropBall(entity player)
 {
        if(player.ballcarried && g_nexball)
@@ -1134,6 +956,7 @@ MUTATOR_HOOKFUNCTION(nb, SendWaypoint)
 
 REGISTER_MUTATOR(nb, g_nexball)
 {
+    MUTATOR_STATIC();
        MUTATOR_ONADD
        {
                g_nexball_meter_period = autocvar_g_nexball_meter_period;
@@ -1153,25 +976,15 @@ REGISTER_MUTATOR(nb, g_nexball)
                InitializeEntity(NULL, nb_delayedinit, INITPRIO_GAMETYPE);
                WEP_NEXBALL.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
 
-               ActivateTeamplay();
-               SetLimits(autocvar_g_nexball_goallimit, autocvar_g_nexball_goalleadlimit, autocvar_timelimit_override, -1);
-               have_team_spawns = -1; // request team spawns
+               GameRules_teams(true);
+               GameRules_limit_score(autocvar_g_nexball_goallimit);
+               GameRules_limit_lead(autocvar_g_nexball_goalleadlimit);
        }
 
        MUTATOR_ONROLLBACK_OR_REMOVE
        {
                WEP_NEXBALL.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
-               // we actually cannot roll back nb_delayedinit here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
        }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
        return 0;
 }
 
diff --git a/qcsrc/common/gamemodes/gamemode/nexball/sv_weapon.qc b/qcsrc/common/gamemodes/gamemode/nexball/sv_weapon.qc
new file mode 100644 (file)
index 0000000..705ac6d
--- /dev/null
@@ -0,0 +1,183 @@
+#include "sv_weapon.qh"
+
+void W_Nexball_Attack(entity actor, .entity weaponentity, float t);
+void W_Nexball_Attack2(entity actor, .entity weaponentity);
+vector trigger_push_calculatevelocity(vector org, entity tgt, float ht);
+
+METHOD(BallStealer, wr_think, void(BallStealer thiswep, entity actor, .entity weaponentity, int fire))
+{
+    TC(BallStealer, thiswep);
+    if(fire & 1)
+        if(weapon_prepareattack(thiswep, actor, weaponentity, false, autocvar_g_balance_nexball_primary_refire))
+            if(autocvar_g_nexball_basketball_meter)
+            {
+                if(actor.ballcarried && !actor.metertime)
+                    actor.metertime = time;
+                else
+                    weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready);
+            }
+            else
+            {
+                W_Nexball_Attack(actor, weaponentity, -1);
+                weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready);
+            }
+    if(fire & 2)
+        if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_nexball_secondary_refire))
+        {
+            W_Nexball_Attack2(actor, weaponentity);
+            weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_nexball_secondary_animtime, w_ready);
+        }
+
+    if(!(fire & 1) && actor.metertime && actor.ballcarried)
+    {
+        W_Nexball_Attack(actor, weaponentity, time - actor.metertime);
+        // DropBall or stealing will set metertime back to 0
+        weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready);
+    }
+}
+
+METHOD(BallStealer, wr_setup, void(BallStealer this, entity actor, .entity weaponentity))
+{
+    TC(BallStealer, this);
+    //weapon_setup(WEP_PORTO.m_id);
+}
+
+METHOD(BallStealer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
+{
+    TC(BallStealer, this);
+}
+
+METHOD(BallStealer, wr_checkammo1, bool(BallStealer this, entity actor, .entity weaponentity))
+{
+    TC(BallStealer, this);
+    return true;
+}
+
+METHOD(BallStealer, wr_checkammo2, bool(BallStealer this, entity actor, .entity weaponentity))
+{
+    TC(BallStealer, this);
+    return true;
+}
+
+void W_Nexball_Think(entity this)
+{
+       //dprint("W_Nexball_Think\n");
+       //vector new_dir = steerlib_arrive(this.enemy.origin, 2500);
+       vector new_dir = normalize(this.enemy.origin + '0 0 50' - this.origin);
+       vector old_dir = normalize(this.velocity);
+       float _speed = vlen(this.velocity);
+       vector new_vel = normalize(old_dir + (new_dir * autocvar_g_nexball_safepass_turnrate)) * _speed;
+       //vector new_vel = (new_dir * autocvar_g_nexball_safepass_turnrate
+
+       this.velocity = new_vel;
+
+       this.nextthink = time;
+}
+
+void W_Nexball_Touch(entity this, entity toucher)
+{
+       entity ball, attacker;
+       attacker = this.owner;
+       //this.think = func_null;
+       //this.enemy = NULL;
+
+       PROJECTILE_TOUCH(this, toucher);
+       if(attacker.team != toucher.team || autocvar_g_nexball_basketball_teamsteal)
+               if((ball = toucher.ballcarried) && !STAT(FROZEN, toucher) && !IS_DEAD(toucher) && (IS_PLAYER(attacker)))
+               {
+                       toucher.velocity = toucher.velocity + normalize(this.velocity) * toucher.damageforcescale * autocvar_g_balance_nexball_secondary_force;
+                       UNSET_ONGROUND(toucher);
+                       if(!attacker.ballcarried)
+                       {
+                               LogNB("stole", attacker);
+                               _sound(toucher, CH_TRIGGER, ball.noise2, VOL_BASE, ATTEN_NORM);
+
+                               if(SAME_TEAM(attacker, toucher) && time > CS(attacker).teamkill_complain)
+                               {
+                                       CS(attacker).teamkill_complain = time + 5;
+                                       CS(attacker).teamkill_soundtime = time + 0.4;
+                                       CS(attacker).teamkill_soundsource = toucher;
+                               }
+
+                               GiveBall(attacker, toucher.ballcarried);
+                       }
+               }
+       delete(this);
+}
+
+void W_Nexball_Attack(entity actor, .entity weaponentity, float t)
+{
+       entity ball;
+       float mul, mi, ma;
+       if(!(ball = actor.ballcarried))
+               return;
+
+       W_SetupShot(actor, weaponentity, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0);
+       tracebox(w_shotorg, BALL_MINS, BALL_MAXS, w_shotorg, MOVE_WORLDONLY, NULL);
+       if(trace_startsolid)
+       {
+               if(actor.metertime)
+                       actor.metertime = 0; // Shot failed, hide the power meter
+               return;
+       }
+
+       //Calculate multiplier
+       if(t < 0)
+               mul = 1;
+       else
+       {
+               mi = autocvar_g_nexball_basketball_meter_minpower;
+               ma = max(mi, autocvar_g_nexball_basketball_meter_maxpower); // avoid confusion
+               //One triangle wave period with 1 as max
+               mul = 2 * (t % g_nexball_meter_period) / g_nexball_meter_period;
+               if(mul > 1)
+                       mul = 2 - mul;
+               mul = mi + (ma - mi) * mul; // range from the minimal power to the maximal power
+       }
+
+       DropBall(ball, w_shotorg, W_CalculateProjectileVelocity(actor, actor.velocity, w_shotdir * autocvar_g_balance_nexball_primary_speed * mul, false));
+
+
+       //TODO: use the speed_up cvar too ??
+}
+
+void W_Nexball_Attack2(entity actor, .entity weaponentity)
+{
+       if(actor.ballcarried.enemy)
+       {
+               entity _ball = actor.ballcarried;
+               W_SetupShot(actor, weaponentity, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0);
+               DropBall(_ball, w_shotorg, trigger_push_calculatevelocity(_ball.origin, _ball.enemy, 32));
+               setthink(_ball, W_Nexball_Think);
+               _ball.nextthink = time;
+               return;
+       }
+
+       if(!autocvar_g_nexball_tackling)
+               return;
+
+       W_SetupShot(actor, weaponentity, false, 2, SND_NB_SHOOT2, CH_WEAPON_A, 0);
+       entity missile = new(ballstealer);
+
+       missile.owner = actor;
+
+       set_movetype(missile, MOVETYPE_FLY);
+       PROJECTILE_MAKETRIGGER(missile);
+
+       //setmodel(missile, "models/elaser.mdl");  // precision set below
+       setsize(missile, '0 0 0', '0 0 0');
+       setorigin(missile, w_shotorg);
+
+       W_SetupProjVelocity_Basic(missile, autocvar_g_balance_nexball_secondary_speed, 0);
+       missile.angles = vectoangles(missile.velocity);
+       settouch(missile, W_Nexball_Touch);
+       setthink(missile, SUB_Remove);
+       missile.nextthink = time + autocvar_g_balance_nexball_secondary_lifetime; //FIXME: use a distance instead?
+
+       missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
+       missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
+
+       CSQCProjectile(missile, true, PROJECTILE_ELECTRO, true);
+}
diff --git a/qcsrc/common/gamemodes/gamemode/nexball/sv_weapon.qh b/qcsrc/common/gamemodes/gamemode/nexball/sv_weapon.qh
new file mode 100644 (file)
index 0000000..6f70f09
--- /dev/null
@@ -0,0 +1 @@
+#pragma once
index 223a81f..0150de3 100644 (file)
@@ -426,8 +426,8 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker
                pointparticles(EFFECT_ROCKET_EXPLODE, this.origin, '0 0 0', 1);
                Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(this.team, INFO_ONSLAUGHT_CPDESTROYED), this.owner.message, attacker.netname);
 
-               PlayerScore_Add(attacker, SP_ONS_TAKES, 1);
-               PlayerScore_Add(attacker, SP_SCORE, 10);
+               GameRules_scoring_add(attacker, ONS_TAKES, 1);
+               GameRules_scoring_add(attacker, SCORE, 10);
 
                this.owner.goalentity = NULL;
                this.owner.islinked = false;
@@ -555,8 +555,8 @@ void ons_ControlPoint_Icon_BuildThink(entity this)
                        Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ONSLAUGHT_CAPTURE, this.owner.ons_toucher.netname, this.owner.message);
                        Send_Notification(NOTIF_ALL_EXCEPT, this.owner.ons_toucher, MSG_CENTER, APP_TEAM_NUM(this.owner.ons_toucher.team, CENTER_ONS_CAPTURE_TEAM), this.owner.message);
                        Send_Notification(NOTIF_ONE, this.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE, this.owner.message);
-                       PlayerScore_Add(this.owner.ons_toucher, SP_ONS_CAPS, 1);
-                       PlayerTeamScore_AddScore(this.owner.ons_toucher, 10);
+                       GameRules_scoring_add(this.owner.ons_toucher, ONS_CAPS, 1);
+                       GameRules_scoring_add_team(this.owner.ons_toucher, SCORE, 10);
                }
 
                this.owner.ons_toucher = NULL;
@@ -911,7 +911,7 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d
                else
                {
                        Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(this.team, INFO_ONSLAUGHT_GENDESTROYED));
-                       PlayerScore_Add(attacker, SP_SCORE, 100);
+                       GameRules_scoring_add(attacker, SCORE, 100);
                }
                this.iscaptured = false;
                this.islinked = false;
@@ -1377,8 +1377,8 @@ void havocbot_goalrating_ons_controlpoints_attack(entity this, float ratingscale
                        best.cnt += 1;
 
                        this.havocbot_attack_time = 0;
-                       if(checkpvs(this.view_ofs,cp))
-                       if(checkpvs(this.view_ofs,best))
+                       if(checkpvs(this.origin + this.view_ofs, cp))
+                       if(checkpvs(this.origin + this.view_ofs, best))
                                this.havocbot_attack_time = time + 2;
                }
                else
@@ -1448,8 +1448,8 @@ bool havocbot_goalrating_ons_generator_attack(entity this, float ratingscale)
                        bestwp.cnt += 1;
 
                        this.havocbot_attack_time = 0;
-                       if(checkpvs(this.view_ofs,g))
-                       if(checkpvs(this.view_ofs,bestwp))
+                       if(checkpvs(this.origin + this.view_ofs, g))
+                       if(checkpvs(this.origin + this.view_ofs, bestwp))
                                this.havocbot_attack_time = time + 5;
 
                        return true;
@@ -2174,11 +2174,11 @@ void ons_ScoreRules()
        if(c2 >= 0) teams |= BIT(1);
        if(c3 >= 0) teams |= BIT(2);
        if(c4 >= 0) teams |= BIT(3);
-       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true);
-       ScoreInfo_SetLabel_TeamScore  (ST_ONS_CAPS,     "destroyed", SFL_SORT_PRIO_PRIMARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_ONS_CAPS,    "caps",      SFL_SORT_PRIO_SECONDARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_ONS_TAKES,    "takes",     0);
-       ScoreRules_basics_end();
+       GameRules_scoring(teams, SFL_SORT_PRIO_PRIMARY, 0, {
+           field_team(ST_ONS_CAPS, "destroyed", SFL_SORT_PRIO_PRIMARY);
+           field(SP_ONS_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);
+           field(SP_ONS_TAKES, "takes", 0);
+       });
 }
 
 void ons_DelayedInit(entity this) // Do this check with a delay so we can wait for teams to be set up
index 0757d7b..5c7fd46 100644 (file)
@@ -5,30 +5,14 @@ void ons_Initialize();
 
 REGISTER_MUTATOR(ons, false)
 {
+    MUTATOR_STATIC();
        MUTATOR_ONADD
        {
-               if (time > 1) // game loads at time 1
-                       error("This is a game type and it cannot be added at runtime.");
-               ons_Initialize();
-
-               ActivateTeamplay();
-               SetLimits(autocvar_g_onslaught_point_limit, autocvar_leadlimit_override, autocvar_timelimit_override, -1);
-               have_team_spawns = -1; // request team spawns
-       }
+               GameRules_teams(true);
+               GameRules_limit_score(autocvar_g_onslaught_point_limit);
 
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back ons_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
+               ons_Initialize();
        }
-
        return false;
 }
 
diff --git a/qcsrc/common/gamemodes/rules.qc b/qcsrc/common/gamemodes/rules.qc
new file mode 100644 (file)
index 0000000..5cfbba2
--- /dev/null
@@ -0,0 +1 @@
+#include "rules.qh"
diff --git a/qcsrc/common/gamemodes/rules.qh b/qcsrc/common/gamemodes/rules.qh
new file mode 100644 (file)
index 0000000..542548d
--- /dev/null
@@ -0,0 +1,5 @@
+#pragma once
+
+#ifdef SVQC
+#include <common/gamemodes/sv_rules.qh>
+#endif
diff --git a/qcsrc/common/gamemodes/sv_rules.qc b/qcsrc/common/gamemodes/sv_rules.qc
new file mode 100644 (file)
index 0000000..a4a4bcd
--- /dev/null
@@ -0,0 +1,112 @@
+#include "sv_rules.qh"
+
+#include <server/teamplay.qh>
+
+void GameRules_teams(bool value)
+{
+    if (value) {
+        serverflags |= SERVERFLAG_TEAMPLAY;
+        teamplay = 1;
+        cvar_set("teamplay", "2");  // DP needs this for sending proper getstatus replies.
+        GameRules_spawning_teams(true);
+    } else {
+       serverflags &= ~SERVERFLAG_TEAMPLAY;
+       teamplay = 0;
+       cvar_set("teamplay", "0");  // DP needs this for sending proper getstatus replies.
+       GameRules_spawning_teams(false);
+    }
+}
+
+void GameRules_spawning_teams(bool value)
+{
+    have_team_spawns = value ? -1 : 0;
+}
+
+bool _GameRules_score_enabled = true;
+void GameRules_score_enabled(bool value)
+{
+    _GameRules_score_enabled = value;
+}
+
+bool GameRules_limit_score_initialized;
+void GameRules_limit_score(int limit)
+{
+    if (GameRules_limit_score_initialized) return;
+    if (autocvar_g_campaign) return;
+    if (limit < 0) return;
+    cvar_set("fraglimit", ftos(limit));
+    GameRules_limit_score_initialized = true;
+}
+
+bool GameRules_limit_lead_initialized;
+void GameRules_limit_lead(int limit)
+{
+    if (GameRules_limit_lead_initialized) return;
+    if (autocvar_g_campaign) return;
+    if (limit < 0) return;
+    cvar_set("leadlimit", ftos(limit));
+    GameRules_limit_lead_initialized = true;
+}
+
+bool GameRules_limit_time_initialized;
+void GameRules_limit_time(int limit)
+{
+    if (GameRules_limit_time_initialized) return;
+    if (autocvar_g_campaign) return;
+    if (limit < 0) return;
+    cvar_set("timelimit", ftos(limit));
+    GameRules_limit_time_initialized = true;
+}
+
+bool GameRules_limit_time_qualifying_initialized;
+void GameRules_limit_time_qualifying(int limit)
+{
+    if (GameRules_limit_time_qualifying_initialized) return;
+    if (autocvar_g_campaign) return;
+    if (limit < 0) return;
+    cvar_set("g_race_qualifying_timelimit", ftos(limit));
+    GameRules_limit_time_qualifying_initialized = true;
+}
+
+void GameRules_limit_fallbacks()
+{
+    GameRules_limit_score(autocvar_fraglimit_override);
+    GameRules_limit_lead(autocvar_leadlimit_override);
+    GameRules_limit_time(autocvar_timelimit_override);
+}
+
+void _GameRules_scoring_begin(int teams, float spprio, float stprio)
+{
+    ScoreRules_basics(teams, spprio, stprio, _GameRules_score_enabled);
+}
+void _GameRules_scoring_field(entity i, string label, int scoreflags)
+{
+    ScoreInfo_SetLabel_PlayerScore(i, label, scoreflags);
+}
+void _GameRules_scoring_field_team(float i, string label, int scoreflags)
+{
+    ScoreInfo_SetLabel_TeamScore(i, label, scoreflags);
+}
+void _GameRules_scoring_end()
+{
+    ScoreRules_basics_end();
+}
+
+.bool m_GameRules_scoring_vip;
+void GameRules_scoring_vip(entity player, bool value)
+{
+    player.m_GameRules_scoring_vip = value;
+}
+bool GameRules_scoring_is_vip(entity player)
+{
+    return player.m_GameRules_scoring_vip;
+}
+
+float _GameRules_scoring_add(entity client, entity sp, float value)
+{
+    return PlayerScore_Add(client, sp, value);
+}
+float _GameRules_scoring_add_team(entity client, entity sp, int st, float value)
+{
+    return PlayerTeamScore_Add(client, sp, st, value);
+}
diff --git a/qcsrc/common/gamemodes/sv_rules.qh b/qcsrc/common/gamemodes/sv_rules.qh
new file mode 100644 (file)
index 0000000..35a643d
--- /dev/null
@@ -0,0 +1,56 @@
+#pragma once
+
+// todo: accept the number of teams as a parameter
+void GameRules_teams(bool value);
+
+/**
+ * Used to disable team spawns in team modes
+ */
+void GameRules_spawning_teams(bool value);
+
+/**
+ * Disabling score disables the "score" column on the scoreboard
+ */
+void GameRules_score_enabled(bool value);
+
+void GameRules_limit_score(int limit);
+void GameRules_limit_lead(int limit);
+void GameRules_limit_time(int limit);
+void GameRules_limit_time_qualifying(int limit);
+
+/**
+ * Set any unspecified rules to their defaults
+ */
+void GameRules_limit_fallbacks();
+
+/**
+ * @param teams a bitmask of active teams
+ * @param spprio player score priority (if frags aren't enabled)
+ * @param stprio team score priority (if frags aren't enabled)
+ */
+#define GameRules_scoring(teams, spprio, stprio, fields) MACRO_BEGIN { \
+    _GameRules_scoring_begin((teams), (spprio), (stprio)); \
+    noref void(entity, string, float) field = _GameRules_scoring_field; \
+    /* todo: just have the one `field` function */ \
+    noref void(int, string, float) field_team = _GameRules_scoring_field_team; \
+    LAMBDA(fields); \
+    _GameRules_scoring_end(); \
+} MACRO_END
+
+void _GameRules_scoring_begin(int teams, float spprio, float stprio);
+void _GameRules_scoring_field(entity i, string label, int scoreflags);
+void _GameRules_scoring_field_team(float i, string label, int scoreflags);
+void _GameRules_scoring_end();
+
+/**
+ * Mark a player as being 'important' (flag carrier, ball carrier, etc)
+ * @param player the entity to mark
+ * @param value VIP status
+ */
+void GameRules_scoring_vip(entity player, bool value);
+bool GameRules_scoring_is_vip(entity player);
+
+#define GameRules_scoring_add(client, fld, value) _GameRules_scoring_add(client, SP_##fld, value)
+float _GameRules_scoring_add(entity client, entity sp, float value);
+#define GameRules_scoring_add_team(client, fld, value) _GameRules_scoring_add_team(client, SP_##fld, ST_##fld, value)
+float _GameRules_scoring_add_team(entity client, entity sp, int st, float value);
index 14c5a34..623f71b 100644 (file)
@@ -26,7 +26,7 @@ GENERIC_COMMAND(dumpitems, "Dump all items to the console") {
         }
         default:
         case CMD_REQUEST_USAGE: {
-            LOG_INFOF("\nUsage:^3 %s dumpitems", GetProgramCommandPrefix());
+            LOG_INFOF("Usage:^3 %s dumpitems", GetProgramCommandPrefix());
             return;
         }
     }
index 7072261..c302ae4 100644 (file)
@@ -67,7 +67,7 @@ CLASS(GameItem, Object)
     METHOD(GameItem, show, void(GameItem this))
     {
         TC(GameItem, this);
-        LOG_INFO("A game item\n");
+        LOG_INFO("A game item");
     }
     void ITEM_HANDLE(Show, GameItem this) { this.show(this); }
 ENDCLASS(GameItem)
index fae573c..39cf78c 100644 (file)
@@ -37,7 +37,7 @@ CLASS(Pickup, GameItem)
     METHOD(Pickup, show, void(Pickup this))
     {
         TC(Pickup, this);
-        LOG_INFOF("%s: %s\n", etos(this), this.m_name);
+        LOG_INFOF("%s: %s", etos(this), this.m_name);
     }
     ATTRIB(Pickup, m_itemid, int, 0);
 #ifdef SVQC
index f6a1481..62600a9 100644 (file)
@@ -283,7 +283,7 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp
        }
        if(fh < 0)
                return 0;
-       LOG_INFO("Analyzing ", fn, " to generate initial mapinfo\n");
+       LOG_INFO("Analyzing ", fn, " to generate initial mapinfo");
 
        inWorldspawn = 2;
        MapInfo_Map_flags = 0;
@@ -1190,7 +1190,7 @@ void MapInfo_LoadMap(string s, float reinit)
        //      MapInfo_SwitchGameType(MAPINFO_TYPE_DEATHMATCH.m_flags);
        //}
 
-       LOG_INFO("Switching to map ", s, "\n");
+       LOG_INFO("Switching to map ", s);
 
        cvar_settemp_restore();
        if(reinit)
index 4c0fd78..2dd8459 100644 (file)
@@ -458,7 +458,7 @@ REGISTER_GAMETYPE(KEEPAWAY, NEW(Keepaway));
 CLASS(Invasion, Gametype)
     INIT(Invasion)
     {
-        this.gametype_init(this, _("Invasion"),"inv","g_invasion",false,"","pointlimit=50 teams=0",_("Survive against waves of monsters"));
+        this.gametype_init(this, _("Invasion"),"inv","g_invasion",false,"","pointlimit=50 teams=0 type=0",_("Survive against waves of monsters"));
     }
     METHOD(Invasion, m_parse_mapinfo, bool(string k, string v))
     {
@@ -466,6 +466,9 @@ CLASS(Invasion, Gametype)
             case "teams":
                 cvar_set("g_invasion_teams", v);
                 return true;
+            case "type":
+                cvar_set("g_invasion_type", v);
+                return true;
         }
         return false;
     }
index cda2e5d..4790f1f 100644 (file)
@@ -348,7 +348,7 @@ void bd_move(entity minigame, entity player, string dir)
                        entity dozer = bd_find_dozer(minigame);
                        if(!dozer)
                        {
-                               LOG_INFO("Dozer wasn't found!\n");
+                               LOG_INFO("Dozer wasn't found!");
                                return; // should not happen... TODO: end match?
                        }
 
@@ -740,7 +740,7 @@ bool bd_save_level(entity minigame)
 
                if(boulder_count != target_count)
                {
-                       LOG_INFO("Not enough targets or boulders, fix your level!\n");
+                       LOG_INFO("Not enough targets or boulders, fix your level!");
                        return false;
                }
 
@@ -791,7 +791,7 @@ void bd_load_level(entity minigame)
        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");
+               LOG_INFO("^3BULLDOZER: ^7could not find storage file ^3", file_name, "^7, no items were loaded");
        }
        else
        {
@@ -829,7 +829,7 @@ void bd_close_editor(entity minigame, entity player)
        entity dozer = bd_find_dozer(minigame);
        if(!dozer)
        {
-               LOG_INFO("You need to place a bulldozer on the level to save it!\n");
+               LOG_INFO("You need to place a bulldozer on the level to save it!");
                return;
        }
 
@@ -840,7 +840,7 @@ void bd_close_editor(entity minigame, entity player)
        }
        else
        {
-               LOG_INFO("You need to set the level name!\n");
+               LOG_INFO("You need to set the level name!");
                return;
        }
 }
index 5307ccd..80cd21b 100644 (file)
@@ -943,7 +943,7 @@ void Monster_Dead(entity this, entity attacker, float gibbed)
 
        if(IS_PLAYER(attacker))
        if(autocvar_g_monsters_score_spawned || !((this.spawnflags & MONSTERFLAG_SPAWNED) || (this.spawnflags & MONSTERFLAG_RESPAWNED)))
-               PlayerScore_Add(attacker, SP_SCORE, +autocvar_g_monsters_score_kill);
+               GameRules_scoring_add(attacker, SCORE, +autocvar_g_monsters_score_kill);
 
        if(gibbed)
        {
index 4bbe2ce..d6989ad 100644 (file)
@@ -16,11 +16,12 @@ entity spawnmonster (entity e, string monster, int monster_id, entity spawnedby,
        //if(invincible) { e.spawnflags |= MONSTERFLAG_INVINCIBLE; }
 
        setorigin(e, orig);
+       bool allow_any = boolean(monster == "anyrandom");
 
-       if(monster == "random")
+       if(monster == "random" || allow_any)
        {
                RandomSelection_Init();
-               FOREACH(Monsters, it != MON_Null && !(it.spawnflags & MONSTER_TYPE_PASSIVE) && !(it.spawnflags & MON_FLAG_HIDDEN),
+               FOREACH(Monsters, it != MON_Null && (allow_any || (!(it.spawnflags & MONSTER_TYPE_PASSIVE) && !(it.spawnflags & MON_FLAG_HIDDEN))),
                {
                        RandomSelection_AddEnt(it, 1, 1);
                });
index 2b932b2..4f940c4 100644 (file)
@@ -280,6 +280,20 @@ STATIC_INIT_LATE(Mutators) {
 #define MUTATOR_ONADD                   if (mode == MUTATOR_ADDING)
 #define MUTATOR_ONREMOVE                if (mode == MUTATOR_REMOVING)
 #define MUTATOR_ONROLLBACK_OR_REMOVE    if (mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK)
+
+#define MUTATOR_STATIC() MACRO_BEGIN { \
+    MUTATOR_ONADD { \
+        /* game loads at time 1 */ \
+        if (time > 1) { \
+            error("This is a game type and it cannot be added at runtime."); \
+        } \
+    } \
+       MUTATOR_ONREMOVE { \
+               LOG_INFO("This is a game type and it cannot be removed at runtime."); \
+               return -1; \
+       } \
+} MACRO_END
+
 #define MUTATOR_ADD(name)               Mutator_Add(MUTATOR_##name)
 #define MUTATOR_REMOVE(name)            Mutator_Remove(MUTATOR_##name)
 #define MUTATOR_RETURNVALUE             CallbackChain_ReturnValue
@@ -305,7 +319,7 @@ STATIC_INIT_LATE(Mutators) {
 #define MUTATOR_HOOK(cb, func, order) MACRO_BEGIN {                     \
     MUTATOR_ONADD {                                                     \
         if (!CallbackChain_Add(HOOK_##cb, CALLBACK_##func, order)) {    \
-            LOG_INFO("HOOK FAILED: ", #cb, ":", #func, "\n");           \
+            LOG_INFO("HOOK FAILED: ", #cb, ":", #func);                 \
             return true;                                                \
         }                                                               \
     }                                                                   \
index fbb6bcb..53042b8 100644 (file)
@@ -158,13 +158,9 @@ CLASS(DamageText, Object)
         if (this.text) strunzone(this.text);
         this.text = strzone(s);
 
-        float size_range = autocvar_cl_damagetext_size_max - autocvar_cl_damagetext_size_min;
-        float damage_range = autocvar_cl_damagetext_size_max_damage - autocvar_cl_damagetext_size_min_damage;
-        float scale_factor = size_range / damage_range;
-        this.m_size = bound(
-            autocvar_cl_damagetext_size_min,
-            (potential - autocvar_cl_damagetext_size_min_damage) * scale_factor + autocvar_cl_damagetext_size_min,
-            autocvar_cl_damagetext_size_max);
+        this.m_size = map_bound_ranges(potential,
+            autocvar_cl_damagetext_size_min_damage, autocvar_cl_damagetext_size_max_damage,
+            autocvar_cl_damagetext_size_min, autocvar_cl_damagetext_size_max);
     }
 
     CONSTRUCTOR(DamageText, int _group, vector _origin, bool _screen_coords, int _health, int _armor, int _potential_damage, int _deathtype, bool _friendlyfire) {
index 0e170e5..4a18cc9 100644 (file)
@@ -1,13 +1,13 @@
 #include "sv_damagetext.qh"
 
-AUTOCVAR(sv_damagetext, int, 2, "<= 0: disabled, >= 1: spectators, >= 2: players, >= 3: all players");
+AUTOCVAR(sv_damagetext, int, 2, "<= 0: disabled, >= 1: visible to spectators, >= 2: visible to attacker, >= 3: all players see everyone's damage");
 
 REGISTER_MUTATOR(damagetext, true);
 
-#define SV_DAMAGETEXT_DISABLED()        (autocvar_sv_damagetext <= 0 /* disabled */)
-#define SV_DAMAGETEXT_SPECTATORS_ONLY() (autocvar_sv_damagetext >= 1 /* spectators only */)
-#define SV_DAMAGETEXT_PLAYERS()         (autocvar_sv_damagetext >= 2 /* players */)
-#define SV_DAMAGETEXT_ALL()             (autocvar_sv_damagetext >= 3 /* all players */)
+#define SV_DAMAGETEXT_DISABLED()        (autocvar_sv_damagetext <= 0 || autocvar_g_instagib)
+#define SV_DAMAGETEXT_SPECTATORS_ONLY() (autocvar_sv_damagetext >= 1)
+#define SV_DAMAGETEXT_PLAYERS()         (autocvar_sv_damagetext >= 2)
+#define SV_DAMAGETEXT_ALL()             (autocvar_sv_damagetext >= 3)
 MUTATOR_HOOKFUNCTION(damagetext, PlayerDamaged) {
     if (SV_DAMAGETEXT_DISABLED()) return;
     const entity attacker = M_ARGV(0, entity);
index d62aa42..70aac4d 100644 (file)
@@ -104,19 +104,20 @@ REGISTER_MUTATOR(dodging, true);
 .int pressedkeys;
 #endif
 
-// returns 1 if the player is close to a wall
+// returns true if the player is close to a wall
 bool check_close_to_wall(entity this, float threshold)
 {
        if (PHYS_DODGING_WALL == 0) { return false; }
 
-#define X(OFFSET) \
-       tracebox(this.origin, this.mins, this.maxs, this.origin + OFFSET, true, this); \
-       if(trace_fraction < 1 && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY) && vdist(this.origin - trace_endpos, <, threshold)) \
+#define X(dir) \
+       tracebox(this.origin, this.mins, this.maxs, this.origin + threshold * dir, true, this); \
+       if (trace_fraction < 1 && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) \
                return true;
-       X(1000*v_right);
-       X(-1000*v_right);
-       X(1000*v_forward);
-       X(-1000*v_forward);
+
+       X(v_right);
+       X(-v_right);
+       X(v_forward);
+       X(-v_forward);
 #undef X
 
        return false;
index 090ff82..18edd48 100644 (file)
@@ -889,20 +889,18 @@ void toss_nade(entity e, bool set_owner, vector _velocity, float _time)
        delete(e.fake_nade);
        e.fake_nade = NULL;
 
+       Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER, CPID_NADES);
+
        makevectors(e.v_angle);
 
        // NOTE: always throw from first weapon entity?
        W_SetupShot(e, _nade.weaponentity_fld, false, false, SND_Null, CH_WEAPON_A, 0);
 
-       Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER, CPID_NADES);
-
        vector offset = (v_forward * autocvar_g_nades_throw_offset.x)
-                                 + (v_right * autocvar_g_nades_throw_offset.y)
-                                 + (v_up * autocvar_g_nades_throw_offset.z);
-       if(autocvar_g_nades_throw_offset == '0 0 0')
-               offset = '0 0 0';
+                     + (v_right * autocvar_g_nades_throw_offset.y)
+                     + (v_up * autocvar_g_nades_throw_offset.z);
 
-       setorigin(_nade, w_shotorg + offset + (v_right * 25) * -1);
+       setorigin(_nade, w_shotorg + offset);
        //setmodel(_nade, MDL_PROJECTILE_NADE);
        //setattachment(_nade, NULL, "");
        PROJECTILE_MAKETRIGGER(_nade);
@@ -1240,7 +1238,7 @@ MUTATOR_HOOKFUNCTION(nades, PlayerPreThink)
                        FOR_EACH_KH_KEY(key) if(key.owner == player) { ++key_count; }
 
                        float time_score;
-                       if(player.flagcarried || player.ballcarried) // this player is important
+                       if(GameRules_scoring_is_vip(player))
                                time_score = autocvar_g_nades_bonus_score_time_flagcarrier;
                        else
                                time_score = autocvar_g_nades_bonus_score_time;
@@ -1379,7 +1377,7 @@ MUTATOR_HOOKFUNCTION(nades, PlayerDies, CBC_ORDER_LAST)
 
                if (SAME_TEAM(frag_attacker, frag_target) || frag_attacker == frag_target)
                        nades_RemoveBonus(frag_attacker);
-               else if(frag_target.flagcarried)
+               else if(GameRules_scoring_is_vip(frag_target))
                        nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_medium);
                else if(autocvar_g_nades_bonus_score_spree && CS(frag_attacker).killcount > 1)
                {
@@ -1481,11 +1479,6 @@ MUTATOR_HOOKFUNCTION(nades, BuildMutatorsString)
        M_ARGV(0, string) = strcat(M_ARGV(0, string), ":Nades");
 }
 
-MUTATOR_HOOKFUNCTION(nades, BuildMutatorsPrettyString)
-{
-       M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Nades");
-}
-
 MUTATOR_HOOKFUNCTION(nades, BuildGameplayTipsString)
 {
        M_ARGV(0, string) = strcat(M_ARGV(0, string), "\n\n^3nades^8 are enabled, press 'g' to use them\n");
index 277a4e7..288c2d5 100644 (file)
@@ -94,7 +94,7 @@ REGISTER_MUTATOR(nt, cvar("g_new_toys") && !cvar("g_instagib") && !cvar("g_overk
 
        MUTATOR_ONREMOVE
        {
-               LOG_INFO("This cannot be removed at runtime\n");
+               LOG_INFO("This cannot be removed at runtime");
                return -1;
        }
 
index fdf942a..0c698e6 100644 (file)
@@ -256,19 +256,8 @@ MUTATOR_HOOKFUNCTION(ok, SetModname)
        return true;
 }
 
-void ok_SetCvars()
-{
-       // hack to force overkill playermodels
-       cvar_settemp("sv_defaultcharacter", "1");
-       cvar_settemp("sv_defaultplayermodel", "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm");
-       cvar_settemp("sv_defaultplayermodel_red", "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm");
-       cvar_settemp("sv_defaultplayermodel_blue", "models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm");
-}
-
 void ok_Initialize()
 {
-       ok_SetCvars();
-
        precache_all_playermodels("models/ok_player/*.dpm");
 
        WEP_RPC.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
index 62b30e2..62781c9 100644 (file)
@@ -23,7 +23,7 @@ REGISTER_MUTATOR(physical_items, cvar("g_physical_items"))
 
        MUTATOR_ONREMOVE
        {
-               LOG_INFO("This cannot be removed at runtime\n");
+               LOG_INFO("This cannot be removed at runtime");
                return -1;
        }
 
index 0fd58c6..93dc602 100644 (file)
@@ -407,7 +407,7 @@ void sandbox_Database_Load()
        if(file_get < 0)
        {
                if(autocvar_g_sandbox_info > 0)
-                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7could not find storage file ^3", file_name, "^7, no objects were loaded\n"));
+                       LOG_INFO("^3SANDBOX - SERVER: ^7could not find storage file ^3", file_name, "^7, no objects were loaded");
        }
        else
        {
@@ -432,7 +432,7 @@ void sandbox_Database_Load()
                        }
                }
                if(autocvar_g_sandbox_info > 0)
-                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7successfully loaded storage file ^3", file_name, "\n"));
+                       LOG_INFO("^3SANDBOX - SERVER: ^7successfully loaded storage file ^3", file_name);
        }
        fclose(file_get);
 }
@@ -524,7 +524,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                _setmodel(e, argv(2));
 
                                if(autocvar_g_sandbox_info > 0)
-                                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " spawned an object at origin ^3", vtos(e.origin), "\n"));
+                                       LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " spawned an object at origin ^3", vtos(e.origin));
                                return true;
 
                        // ---------------- COMMAND: OBJECT, REMOVE ----------------
@@ -533,7 +533,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                if(e != NULL)
                                {
                                        if(autocvar_g_sandbox_info > 0)
-                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " removed an object at origin ^3", vtos(e.origin), "\n"));
+                                               LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " removed an object at origin ^3", vtos(e.origin));
                                        sandbox_ObjectRemove(e);
                                        return true;
                                }
@@ -582,7 +582,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
 
                                                print_to(player, "^2SANDBOX - INFO: ^7Object pasted successfully");
                                                if(autocvar_g_sandbox_info > 0)
-                                                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " pasted an object at origin ^3", vtos(e.origin), "\n"));
+                                                       LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " pasted an object at origin ^3", vtos(e.origin));
                                                return true;
                                }
                                return true;
@@ -617,7 +617,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                                        player.object_attach = NULL; // object was attached, no longer keep it scheduled for attachment
                                                        print_to(player, "^2SANDBOX - INFO: ^7Object attached successfully");
                                                        if(autocvar_g_sandbox_info > 1)
-                                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " attached objects at origin ^3", vtos(e.origin), "\n"));
+                                                               LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " attached objects at origin ^3", vtos(e.origin));
                                                        return true;
                                                }
                                                print_to(player, "^1SANDBOX - WARNING: ^7Object could not be attached to the parent. Make sure you are facing an object that you have edit rights over");
@@ -630,7 +630,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                                        sandbox_ObjectAttach_Remove(e);
                                                        print_to(player, "^2SANDBOX - INFO: ^7Child objects detached successfully");
                                                        if(autocvar_g_sandbox_info > 1)
-                                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " detached objects at origin ^3", vtos(e.origin), "\n"));
+                                                               LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " detached objects at origin ^3", vtos(e.origin));
                                                        return true;
                                                }
                                                print_to(player, "^1SANDBOX - WARNING: ^7Child objects could not be detached. Make sure you are facing an object that you have edit rights over");
@@ -721,7 +721,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                        e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S"));
 
                                        if(autocvar_g_sandbox_info > 1)
-                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin), "\n"));
+                                               LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin));
                                        return true;
                                }
 
index 3a435c5..92c5943 100644 (file)
@@ -12,8 +12,7 @@ MUTATOR_HOOKFUNCTION(vampire, PlayerDamage_SplitHealthArmor)
        if(frag_target != frag_attacker)
        if(!IS_DEAD(frag_target))
        {
-               frag_attacker.health += bound(0, damage_take, frag_target.health);
-               frag_attacker.health = bound(0, frag_attacker.health, autocvar_g_balance_health_limit);
+               GivePlayerHealth(frag_attacker, bound(0, damage_take, frag_target.health));
        }
 }
 
index 9e20392..6dec163 100644 (file)
@@ -530,7 +530,7 @@ void Draw_WaypointSprite(entity this)
     if (rgb == '0 0 0')
     {
         this.teamradar_color = '1 0 1';
-        LOG_INFOF("WARNING: sprite of name %s has no color, using pink so you notice it\n", spriteimage);
+        LOG_INFOF("WARNING: sprite of name %s has no color, using pink so you notice it", spriteimage);
     }
 
     if (time - floor(time) > 0.5)
index 9fac59d..b935075 100644 (file)
@@ -200,7 +200,7 @@ string Process_Notif_Line(
                LOG_INFOF(
                        (
                                "^1TRAILING NEW LINE AT END OF NOTIFICATION: "
-                               "^7net_type = %s, net_name = %s, string = %s.\n"
+                               "^7net_type = %s, net_name = %s, string = %s."
                        ),
                        notiftype,
                        notifname,
@@ -235,7 +235,7 @@ string Process_Notif_Args(
                                        LOG_INFOF(
                                                (
                                                        "^1NOTIFICATION HAS TOO MANY ARGUMENTS: "
-                                                       "^7net_type = %s, net_name = %s, max args = %d.\n"
+                                                       "^7net_type = %s, net_name = %s, max args = %d."
                                                ),
                                                notiftype,
                                                notifname,
@@ -267,7 +267,7 @@ string Process_Notif_Args(
                                                LOG_INFOF(
                                                        (
                                                                "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: "
-                                                               "^7net_type = %s, net_name = %s, args arg = '%s'.\n"
+                                                               "^7net_type = %s, net_name = %s, args arg = '%s'."
                                                        ),
                                                        notiftype,
                                                        notifname,
@@ -286,7 +286,7 @@ string Process_Notif_Args(
                                        LOG_INFOF(
                                                (
                                                        "^1NOTIFICATION HAS TOO MANY ARGUMENTS: "
-                                                       "^7net_type = %s, net_name = %s, max hudargs = %d.\n"
+                                                       "^7net_type = %s, net_name = %s, max hudargs = %d."
                                                ),
                                                notiftype,
                                                notifname,
@@ -318,7 +318,7 @@ string Process_Notif_Args(
                                                LOG_INFOF(
                                                        (
                                                                "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: "
-                                                               "^7net_type = %s, net_name = %s, hudargs arg = '%s'.\n"
+                                                               "^7net_type = %s, net_name = %s, hudargs arg = '%s'."
                                                        ),
                                                        notiftype,
                                                        notifname,
@@ -337,7 +337,7 @@ string Process_Notif_Args(
                                        LOG_INFOF(
                                                (
                                                        "^1NOTIFICATION HAS TOO MANY ARGUMENTS: "
-                                                       "^7net_type = %s, net_name = %s, max durcnt = %d.\n"
+                                                       "^7net_type = %s, net_name = %s, max durcnt = %d."
                                                ),
                                                notiftype,
                                                notifname,
@@ -372,7 +372,7 @@ string Process_Notif_Args(
                                                        LOG_INFOF(
                                                                (
                                                                        "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: "
-                                                                       "^7net_type = %s, net_name = %s, durcnt arg = '%s'.\n"
+                                                                       "^7net_type = %s, net_name = %s, durcnt arg = '%s'."
                                                                ),
                                                                notiftype,
                                                                notifname,
@@ -421,7 +421,7 @@ void Create_Notification_Entity(entity notif,
                        LOG_INFOF(
                                (
                                        "^1NOTIFICATION WITH IMPROPER TYPE: "
-                                       "^7net_type = %d, net_name = %s.\n"
+                                       "^7net_type = %d, net_name = %s."
                                ),
                                typeId,
                                namestring
@@ -471,7 +471,7 @@ void Create_Notification_Entity_Annce(entity notif,
                                        LOG_INFOF(
                                                (
                                                        "^1NOTIFICATION WITH NO SOUND: "
-                                                       "^7net_type = %s, net_name = %s.\n"
+                                                       "^7net_type = %s, net_name = %s."
                                                ),
                                                typestring,
                                                namestring
@@ -529,7 +529,7 @@ void Create_Notification_Entity_InfoCenter(entity notif,
                                                LOG_INFOF(
                                                        (
                                                                "^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: "
-                                                               "^7net_type = %s, net_name = %s, strnum = %d, flnum = %d\n"
+                                                               "^7net_type = %s, net_name = %s, strnum = %d, flnum = %d"
                                                        ),
                                                        typestring,
                                                        namestring,
@@ -563,7 +563,7 @@ void Create_Notification_Entity_InfoCenter(entity notif,
                                                LOG_INFOF(
                                                        (
                                                                "^1NOTIFICATION HAS HUDARGS BUT NO ICON: "
-                                                               "^7net_type = %s, net_name = %s.\n"
+                                                               "^7net_type = %s, net_name = %s."
                                                        ),
                                                        typestring,
                                                        namestring
@@ -635,7 +635,7 @@ void Create_Notification_Entity_InfoCenter(entity notif,
                                        LOG_INFOF(
                                                (
                                                        "^1EMPTY NOTIFICATION: "
-                                                       "^7net_type = %s, net_name = %s.\n"
+                                                       "^7net_type = %s, net_name = %s."
                                                ),
                                                typestring,
                                                namestring
@@ -661,7 +661,7 @@ void Create_Notification_Entity_Multi(entity notif,
                                LOG_INFOF(
                                        (
                                                "^1NOTIFICATION WITH NO SUBCALLS: "
-                                               "^7net_type = %s, net_name = %s.\n"
+                                               "^7net_type = %s, net_name = %s."
                                        ),
                                        typestring,
                                        namestring
@@ -713,7 +713,7 @@ void Create_Notification_Entity_Choice(entity notif,
                                LOG_INFOF(
                                        (
                                                "^1NOTIFICATION IS MISSING CHOICE PARAMS: "
-                                               "^7net_type = %s, net_name = %s.\n"
+                                               "^7net_type = %s, net_name = %s."
                                        ),
                                        typestring,
                                        namestring
index 4cc59a5..1721303 100644 (file)
@@ -181,25 +181,25 @@ GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt"
                        if (fh >= 0)
                        {
                                Dump_Notifications(fh, alsoprint);
-                               LOG_INFOF("Dumping notifications... File located in ^2data/data/%s^7.\n", filename);
+                               LOG_INFOF("Dumping notifications... File located in ^2data/data/%s^7.", filename);
                                fclose(fh);
                        }
                        else
                        {
-                               LOG_INFOF("^1Error: ^7Could not open file '%s'!\n", filename);
+                               LOG_INFOF("^1Error: ^7Could not open file '%s'!", filename);
                        }
                        #else
-                       LOG_INFO(_("Notification dump command only works with cl_cmd and sv_cmd.\n"));
+                       LOG_INFO(_("Notification dump command only works with cl_cmd and sv_cmd."));
                        #endif
                        return;
                }
                default:
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpnotifs [filename]"));
-                       LOG_INFO("  Where 'filename' is the file to write (default is notifications_dump.cfg),\n");
-                       LOG_INFO("  if supplied with '-' output to console as well as default,\n");
-                       LOG_INFO("  if left blank, it will only write to default.\n");
+                       LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " dumpnotifs [filename]");
+                       LOG_INFO("  Where 'filename' is the file to write (default is notifications_dump.cfg),");
+                       LOG_INFO("  if supplied with '-' output to console as well as default,");
+                       LOG_INFO("  if left blank, it will only write to default.");
                        return;
                }
        }
index 34518bd..20e2d4c 100644 (file)
@@ -491,7 +491,7 @@ void SpecialCommand(entity this)
        if(autocvar_sv_cheats || this.maycheat)
        {
                if (!CheatImpulse(this, CHIMPULSE_GIVE_ALL.impulse))
-                       LOG_INFO("A hollow voice says \"Plugh\".\n");
+                       LOG_INFO("A hollow voice says \"Plugh\".");
        }
        else
                STAT(MOVEVARS_SPECIALCOMMAND, this) = true;
index 0015da7..d8af629 100644 (file)
@@ -420,7 +420,7 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
                case URL_READY_ERROR:
                default:
                {
-                       LOG_INFO("Player stats writing failed: ", ftos(status), "\n");
+                       LOG_INFO("Player stats writing failed: ", ftos(status));
                        PlayerStats_GameReport_DelayMapVote = false;
                        if(PS_GR_OUT_DB >= 0)
                        {
@@ -434,13 +434,13 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
 
 void PlayerStats_PlayerBasic(entity joiningplayer, float newrequest)
 {
-       PlayerScore_Add(joiningplayer, SP_ELO, -1);
+       GameRules_scoring_add(joiningplayer, ELO, -1);
        // http://stats.xonotic.org/player/GgXRw6piDtFIbMArMuiAi8JG4tiin8VLjZgsKB60Uds=/elo.txt
        if(autocvar_g_playerstats_playerbasic_uri != "")
        {
                string uri = autocvar_g_playerstats_playerbasic_uri;
                if (joiningplayer.crypto_idfp == "") {
-                       PlayerScore_Add(joiningplayer, SP_ELO, -1);
+                       GameRules_scoring_add(joiningplayer, ELO, -1);
                } else {
                        // create the database if it doesn't already exist
                        if(PS_B_IN_DB < 0)
@@ -472,7 +472,7 @@ void PlayerStats_PlayerBasic(entity joiningplayer, float newrequest)
        else
        {
                // server has this disabled, kill the DB and set status to idle
-               PlayerScore_Add(joiningplayer, SP_ELO, -1);
+               GameRules_scoring_add(joiningplayer, ELO, -1);
                if(PS_B_IN_DB >= 0)
                {
                        db_close(PS_B_IN_DB);
@@ -573,7 +573,7 @@ void PlayerStats_PlayerBasic_Handler(entity fh, entity p, float status)
                         if (gt == PlayerStats_GetGametype()) {
                             handled = true;
                             float e = stof(data);
-                            PlayerScore_Add(p, SP_ELO, +1 + e);
+                            GameRules_scoring_add(p, ELO, +1 + e);
                         }
                         if (gt == "") {
                             // PlayerInfo_AddItem(p, value, data);
@@ -590,18 +590,18 @@ void PlayerStats_PlayerBasic_Handler(entity fh, entity p, float status)
                case URL_READY_CLOSED:
                {
                        // url_fclose has finished
-                       LOG_INFO("Player stats synchronized with server\n");
+                       LOG_INFO("Player stats synchronized with server");
                        return;
                }
 
                case URL_READY_ERROR:
                default:
                {
-                       LOG_INFO("Receiving player stats failed: ", ftos(status), "\n");
+                       LOG_INFO("Receiving player stats failed: ", ftos(status));
                        break;
                }
        }
-       PlayerScore_Add(p, SP_ELO, -1);
+       GameRules_scoring_add(p, ELO, -1);
 }
 #endif // SVQC
 
@@ -613,7 +613,7 @@ void PlayerStats_PlayerBasic_Handler(entity fh, entity p, float status)
        float i = 0;
        for(e = PS_D_IN_EVL; (en = db_get(PS_D_IN_DB, e)) != ""; e = en)
        {
-               LOG_INFO(sprintf("%d:%s:%s\n", i, e, db_get(PS_D_IN_DB, sprintf("#%s", e))));
+               LOG_INFOF("%d:%s:%s", i, e, db_get(PS_D_IN_DB, sprintf("#%s", e)));
                ++i;
        }
 #endif
@@ -679,7 +679,7 @@ void PlayerStats_PlayerDetail_CheckUpdate()
        float gamecount = cvar("cl_matchcount");
 
        #if 0
-       LOG_INFOF("PlayerStats_PlayerDetail_CheckUpdate(): %f >= %f, %d > %d\n",
+       LOG_INFOF("PlayerStats_PlayerDetail_CheckUpdate(): %f >= %f, %d > %d",
                time,
                PS_D_NEXTUPDATETIME,
                PS_D_LASTGAMECOUNT,
@@ -782,7 +782,7 @@ void PlayerStats_PlayerDetail_Handler(entity fh, entity unused, float status)
                                                        "PlayerStats_PlayerDetail_Handler(): ERROR: "
                                                        "Key went unhandled? Is our version outdated?\n"
                                                        "PlayerStats_PlayerDetail_Handler(): "
-                                                       "Key '%s', Event '%s', Data '%s'\n",
+                                                       "Key '%s', Event '%s', Data '%s'",
                                                        key,
                                                        event,
                                                        data
@@ -792,13 +792,13 @@ void PlayerStats_PlayerDetail_Handler(entity fh, entity unused, float status)
                                }
 
                                #if 0
-                               LOG_INFO(sprintf(
+                               LOG_INFOF(
                                        "PlayerStats_PlayerDetail_Handler(): "
-                                       "Key '%s', Event '%s', Data '%s'\n",
+                                       "Key '%s', Event '%s', Data '%s'",
                                        key,
                                        event,
                                        data
-                               ));
+                               );
                                #endif
                        }
                        //print("PlayerStats_PlayerDetail_Handler(): End of response.\n");
@@ -811,14 +811,14 @@ void PlayerStats_PlayerDetail_Handler(entity fh, entity unused, float status)
                case URL_READY_CLOSED:
                {
                        // url_fclose has finished
-                       LOG_INFO("PlayerStats_PlayerDetail_Handler(): Player stats synchronized with server.\n");
+                       LOG_INFO("PlayerStats_PlayerDetail_Handler(): Player stats synchronized with server.");
                        break;
                }
 
                case URL_READY_ERROR:
                default:
                {
-                       LOG_INFO("PlayerStats_PlayerDetail_Handler(): Receiving player stats failed: ", ftos(status), "\n");
+                       LOG_INFO("PlayerStats_PlayerDetail_Handler(): Receiving player stats failed: ", ftos(status));
                        PlayerStats_PlayerDetail_Status = PS_D_STATUS_ERROR;
                        if(PS_D_IN_DB >= 0)
                        {
index f5b3b2c..6a6ce3f 100644 (file)
@@ -631,12 +631,46 @@ void Item_ScheduleRespawnIn(entity e, float t)
        }
 }
 
+AUTOCVAR(g_pickup_respawntime_scaling_reciprocal, float, 0.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to 0) can be used to achieve a constant number of items spawned *per player*");
+AUTOCVAR(g_pickup_respawntime_scaling_offset, float, 0.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right - the results are not intuitive and I recommend plotting the respawn time and the number of items per player to see what's happening");
+AUTOCVAR(g_pickup_respawntime_scaling_linear, float, 1.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly");
+
+float adjust_respawntime(float normal_respawntime) {
+       float r = autocvar_g_pickup_respawntime_scaling_reciprocal;
+       float o = autocvar_g_pickup_respawntime_scaling_offset;
+       float l = autocvar_g_pickup_respawntime_scaling_linear;
+
+       if (r == 0 && l == 1) {
+               return normal_respawntime;
+       }
+
+       CheckAllowedTeams(NULL);
+       GetTeamCounts(NULL);
+       int players = 0;
+       if (c1 != -1) players += c1;
+       if (c2 != -1) players += c2;
+       if (c3 != -1) players += c3;
+       if (c4 != -1) players += c4;
+
+       if (players >= 2) {
+               return normal_respawntime * (r / (players + o) + l);
+       } else {
+               return normal_respawntime;
+       }
+}
+
 void Item_ScheduleRespawn(entity e)
 {
        if(e.respawntime > 0)
        {
                Item_Show(e, 0);
-               Item_ScheduleRespawnIn(e, ITEM_RESPAWNTIME(e));
+
+               float adjusted_respawntime = adjust_respawntime(e.respawntime);
+               //LOG_INFOF("item %s will respawn in %f", e.classname, adjusted_respawntime);
+
+               // range: adjusted_respawntime - respawntimejitter .. adjusted_respawntime + respawntimejitter
+               float actual_time = adjusted_respawntime + crandom() * e.respawntimejitter;
+               Item_ScheduleRespawnIn(e, actual_time);
        }
        else // if respawntime is -1, this item does not respawn
                Item_Show(e, -1);
@@ -648,7 +682,119 @@ void Item_ScheduleInitialRespawn(entity e)
        Item_ScheduleRespawnIn(e, max(0, game_starttime - time) + ((e.respawntimestart) ? e.respawntimestart : ITEM_RESPAWNTIME_INITIAL(e)));
 }
 
-float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax, float mode)
+void GivePlayerResource(entity player, .float resource_type, float amount)
+{
+       if (amount == 0)
+       {
+               return;
+       }
+       switch (resource_type)
+       {
+               case health:
+               {
+                       // Ugly hack. We do not check if health goes beyond hard limit since
+                       // currently it is done in player_regen. We need to bring back this
+                       // check when other code is ported to this function.
+                       player.health = bound(player.health, player.health + amount,
+                               autocvar_g_balance_health_limit);
+                       // Correct code:
+                       //player.health = bound(player.health, player.health + amount,
+                       //      min(autocvar_g_balance_health_limit,
+                       //      RESOURCE_AMOUNT_HARD_LIMIT));
+                       player.pauserothealth_finished = max(player.pauserothealth_finished,
+                               time + autocvar_g_balance_pause_health_rot);
+                       return;
+               }
+               case armorvalue:
+               {
+                       // Ugly hack. We do not check if armor goes beyond hard limit since
+                       // currently it is done in player_regen. We need to bring back this
+                       // check when other code is ported to this function.
+                       player.armorvalue = bound(player.armorvalue, player.armorvalue +
+                               amount, autocvar_g_balance_armor_limit);
+                       // Correct code:
+                       //player.armorvalue = bound(player.armorvalue, player.armorvalue +
+                       //      amount, min(autocvar_g_balance_armor_limit,
+                       //      RESOURCE_AMOUNT_HARD_LIMIT));
+                       player.pauserotarmor_finished = max(player.pauserotarmor_finished,
+                               time + autocvar_g_balance_pause_armor_rot);
+                       return;
+               }
+               case ammo_shells:
+               case ammo_nails:
+               case ammo_rockets:
+               case ammo_cells:
+               case ammo_plasma:
+               {
+                       GivePlayerAmmo(player, resource_type, amount);
+                       return;
+               }
+               case ammo_fuel:
+               {
+                       player.ammo_fuel = bound(player.ammo_fuel, player.ammo_fuel +
+                               amount, min(g_pickup_fuel_max, RESOURCE_AMOUNT_HARD_LIMIT));
+                       player.pauserotfuel_finished = max(player.pauserotfuel_finished,
+                               time + autocvar_g_balance_pause_fuel_rot);
+                       return;
+               }
+       }
+}
+
+void GivePlayerHealth(entity player, float amount)
+{
+       GivePlayerResource(player, health, amount);
+}
+
+void GivePlayerArmor(entity player, float amount)
+{
+       GivePlayerResource(player, armorvalue, amount);
+}
+
+void GivePlayerAmmo(entity player, .float ammotype, float amount)
+{
+       if (amount == 0)
+       {
+               return;
+       }
+       float maxvalue = RESOURCE_AMOUNT_HARD_LIMIT;
+       switch (ammotype)
+       {
+               case ammo_shells:
+               {
+                       maxvalue = g_pickup_shells_max;
+                       break;
+               }
+               case ammo_cells:
+               {
+                       maxvalue = g_pickup_cells_max;
+                       break;
+               }
+               case ammo_rockets:
+               {
+                       maxvalue = g_pickup_rockets_max;
+                       break;
+               }
+               case ammo_plasma:
+               {
+                       maxvalue = g_pickup_plasma_max;
+                       break;
+               }
+               case ammo_nails:
+               {
+                       maxvalue = g_pickup_nails_max;
+                       break;
+               }
+       }
+       player.(ammotype) = min(player.(ammotype) + amount,
+               min(maxvalue, RESOURCE_AMOUNT_HARD_LIMIT));
+}
+
+void GivePlayerFuel(entity player, float amount)
+{
+       GivePlayerResource(player, ammo_fuel, amount);
+}
+
+float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax)
 {
        if (!item.(ammotype))
                return false;
@@ -657,8 +803,13 @@ float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax
        {
                if ((player.(ammotype) < ammomax) || item.pickup_anyway > 0)
                {
-                       player.(ammotype) = bound(player.(ammotype), ammomax, player.(ammotype) + item.(ammotype));
-                       goto YEAH;
+                       float amount = item.(ammotype);
+                       if ((player.(ammotype) + amount) > ammomax)
+                       {
+                               amount = ammomax - player.(ammotype);
+                       }
+                       GivePlayerResource(player, ammotype, amount);
+                       return true;
                }
        }
        else if(g_weapon_stay == 2)
@@ -666,29 +817,11 @@ float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax
                float mi = min(item.(ammotype), ammomax);
                if (player.(ammotype) < mi)
                {
-                       player.(ammotype) = mi;
-                       goto YEAH;
+                       GivePlayerResource(player, ammotype, mi - player.(ammotype));
                }
+               return true;
        }
-
        return false;
-
-LABEL(YEAH)
-       switch(mode)
-       {
-               case ITEM_MODE_FUEL:
-                       player.pauserotfuel_finished = max(player.pauserotfuel_finished, time + autocvar_g_balance_pause_fuel_rot);
-                       break;
-               case ITEM_MODE_HEALTH:
-                       player.pauserothealth_finished = max(player.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
-                       break;
-               case ITEM_MODE_ARMOR:
-                       player.pauserotarmor_finished = max(player.pauserotarmor_finished, time + autocvar_g_balance_pause_armor_rot);
-                       break;
-               default:
-                       break;
-       }
-       return true;
 }
 
 float Item_GiveTo(entity item, entity player)
@@ -717,16 +850,14 @@ float Item_GiveTo(entity item, entity player)
                        }
                }
        }
-
-       pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL);
-       pickedup |= Item_GiveAmmoTo(item, player, ammo_shells, g_pickup_shells_max, ITEM_MODE_NONE);
-       pickedup |= Item_GiveAmmoTo(item, player, ammo_nails, g_pickup_nails_max, ITEM_MODE_NONE);
-       pickedup |= Item_GiveAmmoTo(item, player, ammo_rockets, g_pickup_rockets_max, ITEM_MODE_NONE);
-       pickedup |= Item_GiveAmmoTo(item, player, ammo_cells, g_pickup_cells_max, ITEM_MODE_NONE);
-       pickedup |= Item_GiveAmmoTo(item, player, ammo_plasma, g_pickup_plasma_max, ITEM_MODE_NONE);
-       pickedup |= Item_GiveAmmoTo(item, player, health, item.max_health, ITEM_MODE_HEALTH);
-       pickedup |= Item_GiveAmmoTo(item, player, armorvalue, item.max_armorvalue, ITEM_MODE_ARMOR);
-
+       pickedup |= Item_GiveAmmoTo(item, player, health, item.max_health);
+       pickedup |= Item_GiveAmmoTo(item, player, armorvalue, item.max_armorvalue);
+       pickedup |= Item_GiveAmmoTo(item, player, ammo_shells, g_pickup_shells_max);
+       pickedup |= Item_GiveAmmoTo(item, player, ammo_nails, g_pickup_nails_max);
+       pickedup |= Item_GiveAmmoTo(item, player, ammo_rockets, g_pickup_rockets_max);
+       pickedup |= Item_GiveAmmoTo(item, player, ammo_cells, g_pickup_cells_max);
+       pickedup |= Item_GiveAmmoTo(item, player, ammo_plasma, g_pickup_plasma_max);
+       pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max);
        if (item.itemdef.instanceOfWeaponPickup)
        {
                WepSet w;
index e52604d..f557e10 100644 (file)
@@ -4,6 +4,9 @@
 #include <server/defs.qh>
 #endif
 
+/// \brief Unconditional maximum amount of resources the player can have.
+const int RESOURCE_AMOUNT_HARD_LIMIT = 999;
+
 const int AMMO_COUNT = 4; // amount of ammo types to show in the inventory panel
 
 // item networking
@@ -67,8 +70,6 @@ bool have_pickup_item(entity this);
 
 const float ITEM_RESPAWN_TICKS = 10;
 
-#define ITEM_RESPAWNTIME(i)         ((i).respawntime + crandom() * (i).respawntimejitter)
-       // range: respawntime - respawntimejitter .. respawntime + respawntimejitter
 #define ITEM_RESPAWNTIME_INITIAL(i) (ITEM_RESPAWN_TICKS + random() * ((i).respawntime + (i).respawntimejitter - ITEM_RESPAWN_TICKS))
        // range: 10 .. respawntime + respawntimejitter
 
@@ -85,11 +86,40 @@ void Item_ScheduleRespawnIn(entity e, float t);
 void Item_ScheduleRespawn(entity e);
 
 void Item_ScheduleInitialRespawn(entity e);
-float ITEM_MODE_NONE = 0;
-float ITEM_MODE_HEALTH = 1;
-float ITEM_MODE_ARMOR = 2;
-float ITEM_MODE_FUEL = 3;
-float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax, float mode);
+
+/// \brief Gives player a resource such as health, armor or ammo.
+/// \param[in,out] player Player to give resource to.
+/// \param[in] resource_type Type of the resource.
+/// \param[in] amount Amount of resource to give.
+/// \return No return.
+void GivePlayerResource(entity player, .float resource_type, float amount);
+
+/// \brief Gives health to the player.
+/// \param[in,out] player Player to give health to.
+/// \param[in] amount Amount of health to give.
+/// \return No return.
+void GivePlayerHealth(entity player, float amount);
+
+/// \brief Gives armor to the player.
+/// \param[in,out] player Player to give armor to.
+/// \param[in] amount Amount of armor to give.
+/// \return No return.
+void GivePlayerArmor(entity player, float amount);
+
+/// \brief Gives ammo of the specified type to the player.
+/// \param[in,out] player Player to give ammo to.
+/// \param[in] type Ammo type property.
+/// \param[in] amount Amount of ammo to give.
+/// \return No return.
+void GivePlayerAmmo(entity player, .float ammotype, float amount);
+
+/// \brief Gives fuel to the player.
+/// \param[in,out] player Player to give fuel to.
+/// \param[in] amount Amount of fuel to give.
+/// \return No return.
+void GivePlayerFuel(entity player, float amount);
+
+float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax);
 
 float Item_GiveTo(entity item, entity player);
 
index 3c7d47f..8ded50d 100644 (file)
@@ -8,8 +8,11 @@ void button_return(entity this);
 void button_wait(entity this)
 {
        this.state = STATE_TOP;
-       this.nextthink = this.ltime + this.wait;
-       setthink(this, button_return);
+       if(this.wait >= 0)
+       {
+               this.nextthink = this.ltime + this.wait;
+               setthink(this, button_return);
+       }
        SUB_UseTargets(this, this.enemy, NULL);
        this.frame = 1;                 // use alternate textures
 }
@@ -56,6 +59,9 @@ void button_reset(entity this)
        setorigin(this, this.pos1);
        this.frame = 0;                 // use normal textures
        this.state = STATE_BOTTOM;
+       this.velocity = '0 0 0';
+       setthink(this, func_null);
+       this.nextthink = 0;
        if (this.health)
                this.takedamage = DAMAGE_YES;   // can be shot again
 }
@@ -150,6 +156,8 @@ spawnfunc(func_button)
        this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);
     this.flags |= FL_NOTARGET;
 
+    this.reset = button_reset;
+
        button_reset(this);
 }
 #endif
index 9715c25..6268dcf 100644 (file)
@@ -1,5 +1,7 @@
 #include "rotating.qh"
 #ifdef SVQC
+const int FUNC_ROTATING_STARTOFF = BIT(4);
+
 void func_rotating_setactive(entity this, int astate)
 {
        if (astate == ACTIVE_TOGGLE)
@@ -18,6 +20,22 @@ void func_rotating_setactive(entity this, int astate)
                this.avelocity = this.pos1;
 }
 
+void func_rotating_reset(entity this)
+{
+       // TODO: reset angles as well?
+
+       if(this.spawnflags & FUNC_ROTATING_STARTOFF)
+       {
+               this.avelocity = '0 0 0';
+               this.active = ACTIVE_NOT;
+       }
+       else
+       {
+               this.avelocity = this.pos1;
+               this.active = ACTIVE_ACTIVE;
+       }
+}
+
 /*QUAKED spawnfunc_func_rotating (0 .5 .8) ? - - X_AXIS Y_AXIS
 Brush model that spins in place on one axis (default Z).
 speed   : speed to rotate (in degrees per second)
@@ -34,16 +52,15 @@ spawnfunc(func_rotating)
                ambientsound(this.origin, this.noise, VOL_BASE, ATTEN_IDLE);
        }
 
-       this.active = ACTIVE_ACTIVE;
        this.setactive = func_rotating_setactive;
 
        if (!this.speed)
                this.speed = 100;
        // FIXME: test if this turns the right way, then remove this comment (negate as needed)
-       if (this.spawnflags & 4) // X (untested)
+       if (this.spawnflags & BIT(2)) // X (untested)
                this.avelocity = '0 0 1' * this.speed;
        // FIXME: test if this turns the right way, then remove this comment (negate as needed)
-       else if (this.spawnflags & 8) // Y (untested)
+       else if (this.spawnflags & BIT(3)) // Y (untested)
                this.avelocity = '1 0 0' * this.speed;
        // FIXME: test if this turns the right way, then remove this comment (negate as needed)
        else // Z
@@ -51,6 +68,15 @@ spawnfunc(func_rotating)
 
        this.pos1 = this.avelocity;
 
+       // do this after setting pos1, so we can safely reactivate the func_rotating
+       if(this.spawnflags & FUNC_ROTATING_STARTOFF)
+       {
+               this.avelocity = '0 0 0';
+               this.active = ACTIVE_NOT;
+       }
+       else
+               this.active = ACTIVE_ACTIVE;
+
     if(this.dmg && (this.message == ""))
         this.message = " was squished";
     if(this.dmg && (this.message2 == ""))
@@ -72,6 +98,6 @@ spawnfunc(func_rotating)
        this.nextthink = this.ltime + 999999999;
        setthink(this, SUB_NullThink); // for PushMove
 
-       // TODO make a reset function for this one
+       this.reset = func_rotating_reset;
 }
 #endif
index 4eed8ef..1464da9 100644 (file)
@@ -55,7 +55,7 @@ void target_spawn_edit_entity(entity this, entity e, string msg, entity kt, enti
                        data = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", key)));
                        if(data.y == 0) // undefined field, i.e., invalid type
                        {
-                               LOG_INFO("target_spawn: invalid/unknown entity key ", key, " specified, ignored!\n");
+                               LOG_INFO("target_spawn: invalid/unknown entity key ", key, " specified, ignored!");
                                continue;
                        }
                }
@@ -150,7 +150,7 @@ void target_spawn_edit_entity(entity this, entity e, string msg, entity kt, enti
                                }
                                else
                                {
-                                       LOG_INFO("target_spawn: invalid/unknown variable replacement ", value, " specified, ignored!\n");
+                                       LOG_INFO("target_spawn: invalid/unknown variable replacement ", value, " specified, ignored!");
                                        continue;
                                }
 
@@ -163,13 +163,13 @@ void target_spawn_edit_entity(entity this, entity e, string msg, entity kt, enti
                                {
                                        if(value != "")
                                        {
-                                               LOG_INFO("target_spawn: try to get a field of a non-entity, ignored!\n");
+                                               LOG_INFO("target_spawn: try to get a field of a non-entity, ignored!");
                                                continue;
                                        }
                                        data2 = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", valuefield)));
                                        if(data2_y == 0) // undefined field, i.e., invalid type
                                        {
-                                               LOG_INFO("target_spawn: invalid/unknown entity key replacement ", valuefield, " specified, ignored!\n");
+                                               LOG_INFO("target_spawn: invalid/unknown entity key replacement ", valuefield, " specified, ignored!");
                                                continue;
                                        }
                                        value = getentityfieldstring(data2_x, valueent);
@@ -189,7 +189,7 @@ void target_spawn_edit_entity(entity this, entity e, string msg, entity kt, enti
                                                        value = vtos(stov(value) + stov(valueoffset));
                                                        break;
                                                default:
-                                                       LOG_INFO("target_spawn: only string, float and vector fields can do calculations, calculation ignored!\n");
+                                                       LOG_INFO("target_spawn: only string, float and vector fields can do calculations, calculation ignored!");
                                                        break;
                                        }
                                }
@@ -206,7 +206,7 @@ void target_spawn_edit_entity(entity this, entity e, string msg, entity kt, enti
                                                        value = vtos(stov(value) + random() * data2_x * '1 0 0' + random() * data2_y * '0 1 0' + random() * data2_z * '0 0 1');
                                                        break;
                                                default:
-                                                       LOG_INFO("target_spawn: only float and vector fields can do random calculations, calculation ignored!\n");
+                                                       LOG_INFO("target_spawn: only float and vector fields can do random calculations, calculation ignored!");
                                                        break;
                                        }
                                }
index 451afa9..8e9936b 100644 (file)
@@ -206,7 +206,7 @@ entity Simple_TeleportPlayer(entity teleporter, entity player)
 #ifdef SVQC
        if(!e) { sprint(player, "Teleport destination vanished. Sorry... please complain to the mapper.\n"); }
 #elif defined(CSQC)
-       if(!e) { LOG_INFO("Teleport destination could not be found from CSQC.\n"); }
+       if(!e) { LOG_INFO("Teleport destination could not be found from CSQC."); }
 #endif
 
        makevectors(e.mangle);
@@ -237,7 +237,7 @@ void teleport_findtarget(entity this)
                if(e.move_movetype == MOVETYPE_NONE)
                        waypoint_spawnforteleporter(this, e.origin, 0);
                if(e.classname != "info_teleport_destination")
-                       LOG_INFO("^3MAPPER ERROR: teleporter does target an invalid teleport destination entity. Angles will not work.\n");
+                       LOG_INFO("^3MAPPER ERROR: teleporter does target an invalid teleport destination entity. Angles will not work.");
 #endif
        }
 
@@ -292,7 +292,7 @@ void WarpZone_PostTeleportPlayer_Callback(entity pl)
        #elif defined(CSQC)
                if(!(pl.flags & BIT(15))) // FL_PROJECTILE
        #endif
-                       LOG_INFO("A non-projectile got through a warpzone and its owner cleared. It's a ", pl.classname, ".\n");
+                       LOG_INFO("A non-projectile got through a warpzone and its owner cleared. It's a ", pl.classname, ".");
                pl.owner = NULL;
        }
        if(IS_PLAYER(pl))
index 6154f6b..eee61c9 100644 (file)
@@ -19,7 +19,7 @@ void trigger_disablerelay_use(entity this, entity actor, entity trigger)
        }
 
        if((!a) == (!b))
-               LOG_INFO("Invalid use of trigger_disablerelay: ", ftos(a), " relays were on, ", ftos(b), " relays were off!\n");
+               LOG_INFO("Invalid use of trigger_disablerelay: ", ftos(a), " relays were on, ", ftos(b), " relays were off!");
 }
 
 spawnfunc(trigger_disablerelay)
index a600263..ffc04a0 100644 (file)
@@ -72,7 +72,7 @@ void viewloc_init(entity this)
                        break;
                }
 
-       if(!this.enemy) { LOG_INFO("^1FAIL!\n"); delete(this); return; }
+       if(!this.enemy) { LOG_INFO("^1FAIL!"); delete(this); return; }
 
        if(!this.goalentity)
                this.goalentity = this.enemy; // make them match so CSQC knows what to do
@@ -86,7 +86,7 @@ void viewloc_init(entity this)
 spawnfunc(trigger_viewlocation)
 {
        // we won't check target2 here yet, as it may not even need to exist
-       if(this.target == "") { LOG_INFO("^1FAIL!\n"); delete(this); return; }
+       if(this.target == "") { LOG_INFO("^1FAIL!"); delete(this); return; }
 
        EXACTTRIGGER_INIT;
        InitializeEntity(this, viewloc_init, INITPRIO_FINDTARGET);
index 8bd0b14..e63a931 100644 (file)
@@ -38,17 +38,17 @@ GENERIC_COMMAND(dumpturrets, "Dump all turrets into turrets_dump.txt")
             if(tur_config_file >= 0)
             {
                 Dump_Turret_Settings();
-                LOG_INFO(sprintf("Dumping turrets... File located in ^2data/data/%s^7.\n", filename));
+                LOG_INFOF("Dumping turrets... File located in ^2data/data/%s^7.", filename);
                 fclose(tur_config_file);
                 tur_config_file = -1;
                 tur_config_alsoprint = -1;
             }
             else
             {
-                LOG_INFO(sprintf("^1Error: ^7Could not open file '%s'!\n", filename));
+                LOG_INFOF("^1Error: ^7Could not open file '%s'!", filename);
             }
             #else
-            LOG_INFO(_("Turrets dump command only works with sv_cmd.\n"));
+            LOG_INFO(_("Turrets dump command only works with sv_cmd."));
             #endif
             return;
         }
@@ -56,10 +56,10 @@ GENERIC_COMMAND(dumpturrets, "Dump all turrets into turrets_dump.txt")
         default:
         case CMD_REQUEST_USAGE:
         {
-            LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpturrets [filename]"));
-            LOG_INFO("  Where 'filename' is the file to write (default is turrets_dump.cfg),\n");
-            LOG_INFO("  if supplied with '-' output to console as well as default,\n");
-            LOG_INFO("  if left blank, it will only write to default.\n");
+            LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " dumpturrets [filename]");
+            LOG_INFO("  Where 'filename' is the file to write (default is turrets_dump.cfg),");
+            LOG_INFO("  if supplied with '-' output to console as well as default,");
+            LOG_INFO("  if left blank, it will only write to default.");
             return;
         }
     }
index 11d5e5d..d75e4a9 100644 (file)
@@ -112,7 +112,7 @@ void turret_draw2d(entity this)
        if(rgb == '0 0 0')
        {
                this.teamradar_color = '1 0 1';
-               LOG_INFOF("WARNING: sprite of name %s has no color, using pink so you notice it\n", spriteimage);
+               LOG_INFOF("WARNING: sprite of name %s has no color, using pink so you notice it", spriteimage);
        }
 
        txt = this.netname;
index a5a23f9..effabea 100644 (file)
@@ -50,7 +50,7 @@ void Dump_Turret_Settings()
                TUR_CONFIG_WRITETOFILE("// }}}\n")
 
                // step 5: debug info
-               LOG_INFO(sprintf("#%d: %s: %d settings...\n", i, it.turret_name, TUR_CONFIG_COUNT));
+               LOG_INFOF("#%d: %s: %d settings...", i, it.turret_name, TUR_CONFIG_COUNT);
                totalsettings += TUR_CONFIG_COUNT;
        });
 
@@ -60,7 +60,7 @@ void Dump_Turret_Settings()
                config_queue[j] = string_null;
 
        // extra information
-       LOG_INFO(sprintf("Totals: %d turrets, %d settings\n", (Turrets_COUNT - 1), totalsettings));
+       LOG_INFOF("Totals: %d turrets, %d settings", (Turrets_COUNT - 1), totalsettings);
 }
 
 #endif
index 6340c00..deba86c 100644 (file)
@@ -336,17 +336,19 @@ STATIC_INIT(compressShortVector)
 
        if(cvar("developer"))
        {
-               LOG_INFO("Verifying vector compression table...\n");
+               LOG_INFO("Verifying vector compression table...");
                for(i = 0x0F00; i < 0xFFFF; ++i)
                        if(i != compressShortVector(decompressShortVector(i)))
                        {
-                               LOG_INFO("BROKEN vector compression: ", ftos(i));
-                               LOG_INFO(" -> ", vtos(decompressShortVector(i)));
-                               LOG_INFO(" -> ", ftos(compressShortVector(decompressShortVector(i))));
-                               LOG_INFO("\n");
+                               LOG_INFOF(
+                                   "BROKEN vector compression: %s -> %s -> %s",
+                                   ftos(i),
+                                   vtos(decompressShortVector(i)),
+                                   ftos(compressShortVector(decompressShortVector(i)))
+                );
                                error("b0rk");
                        }
-               LOG_INFO("Done.\n");
+               LOG_INFO("Done.");
        }
 }
 
@@ -596,7 +598,7 @@ float cvar_settemp(string tmp_cvar, string tmp_value)
 
        if(!cvar_type(tmp_cvar))
        {
-               LOG_INFOF("Error: cvar %s doesn't exist!\n", tmp_cvar);
+               LOG_INFOF("Error: cvar %s doesn't exist!", tmp_cvar);
                return 0;
        }
 
@@ -638,7 +640,7 @@ int cvar_settemp_restore()
                        ++j;
                }
                else
-                       LOG_INFOF("Error: cvar %s doesn't exist anymore! It can still be restored once it's manually recreated.\n", it.netname);
+                       LOG_INFOF("Error: cvar %s doesn't exist anymore! It can still be restored once it's manually recreated.", it.netname);
        });
 
 #else
@@ -652,7 +654,7 @@ int cvar_settemp_restore()
                        ++j;
                }
                else
-                       print(sprintf("Error: cvar %s doesn't exist anymore! It can still be restored once it's manually recreated.\n", e.netname));
+                       print(sprintf("Error: cvar %s doesn't exist anymore! It can still be restored once it's manually recreated.", e.netname));
        }
 #endif
 
@@ -1362,7 +1364,7 @@ void m_shutdown()
 {
        if(shutdown_running)
        {
-               LOG_INFO("Recursive shutdown detected! Only restoring cvars...\n");
+               LOG_INFO("Recursive shutdown detected! Only restoring cvars...");
        }
        else
        {
index 0d595df..afbf79e 100644 (file)
@@ -639,12 +639,12 @@ CLIENT_COMMAND(weapon_find, "Show spawn locations of a weapon")
                }
                default:
                {
-                       LOG_INFOF("Incorrect parameters for ^2%s^7\n", "weapon_find");
+                       LOG_INFOF("Incorrect parameters for ^2%s^7", "weapon_find");
                }
                case CMD_REQUEST_USAGE:
                {
-                       LOG_INFO("\nUsage:^3 cl_cmd weapon_find weapon\n");
-                       LOG_INFO("  Where 'weapon' is the lowercase weapon name, 'all' or 'unowned'.\n");
+                       LOG_INFO("Usage:^3 cl_cmd weapon_find weapon");
+                       LOG_INFO("  Where 'weapon' is the lowercase weapon name, 'all' or 'unowned'.");
                        return;
                }
        }
index c88e3a7..beaa6cb 100644 (file)
@@ -64,17 +64,17 @@ GENERIC_COMMAND(dumpweapons, "Dump all weapons into weapons_dump.txt") // WEAPON
             if(wep_config_file >= 0)
             {
                 Dump_Weapon_Settings();
-                LOG_INFO(sprintf("Dumping weapons... File located in ^2data/data/%s^7.\n", filename));
+                LOG_INFOF("Dumping weapons... File located in ^2data/data/%s^7.", filename);
                 fclose(wep_config_file);
                 wep_config_file = -1;
                 wep_config_alsoprint = -1;
             }
             else
             {
-                LOG_INFO(sprintf("^1Error: ^7Could not open file '%s'!\n", filename));
+                LOG_INFOF("^1Error: ^7Could not open file '%s'!", filename);
             }
             #else
-            LOG_INFO(_("Weapons dump command only works with sv_cmd.\n"));
+            LOG_INFO(_("Weapons dump command only works with sv_cmd."));
             #endif
             return;
         }
@@ -82,10 +82,10 @@ GENERIC_COMMAND(dumpweapons, "Dump all weapons into weapons_dump.txt") // WEAPON
         default:
         case CMD_REQUEST_USAGE:
         {
-            LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpweapons [filename]"));
-            LOG_INFO("  Where 'filename' is the file to write (default is weapons_dump.cfg),\n");
-            LOG_INFO("  if supplied with '-' output to console as well as default,\n");
-            LOG_INFO("  if left blank, it will only write to default.\n");
+            LOG_INFO("Usage:^3 ", GetProgramCommandPrefix(), " dumpweapons [filename]");
+            LOG_INFO("  Where 'filename' is the file to write (default is weapons_dump.cfg),");
+            LOG_INFO("  if supplied with '-' output to console as well as default,");
+            LOG_INFO("  if left blank, it will only write to default.");
             return;
         }
     }
index 513af52..3323d8e 100644 (file)
@@ -57,7 +57,7 @@ vector damage_explosion_calcpush(vector explosion_f, vector target_v, float spee
        v = explosion_calcpush(explosion_f * speedfactor, m, target_v, 1, 0);
        // the factor we then get is:
        //   1
-       LOG_INFOF("MASS: %f\nv: %v -> %v\nENERGY BEFORE == %f + %f = %f\nENERGY AFTER >= %f\n",
+       LOG_INFOF("MASS: %f\nv: %v -> %v\nENERGY BEFORE == %f + %f = %f\nENERGY AFTER >= %f",
                m,
                target_v, target_v + v,
                target_v * target_v, m * explosion_f * speedfactor * explosion_f * speedfactor, target_v * target_v + m * explosion_f * speedfactor * explosion_f * speedfactor,
index a819477..d2443f1 100644 (file)
@@ -48,7 +48,7 @@ void Dump_Weapon_Settings()
                WEP_CONFIG_WRITETOFILE("// }}}\n");
 
                // step 5: debug info
-               LOG_INFO(sprintf("#%d: %s: %d settings...\n", i, it.m_name, WEP_CONFIG_COUNT));
+               LOG_INFOF("#%d: %s: %d settings...", i, it.m_name, WEP_CONFIG_COUNT);
                totalweapons += 1;
                totalsettings += WEP_CONFIG_COUNT;
        });
@@ -59,5 +59,5 @@ void Dump_Weapon_Settings()
                config_queue[x] = string_null;
 
        // extra information
-       LOG_INFO(sprintf("Totals: %d weapons, %d settings\n", totalweapons, totalsettings));
+       LOG_INFOF("Totals: %d weapons, %d settings", totalweapons, totalsettings);
 }
index ea2e2e1..4be2244 100644 (file)
@@ -198,6 +198,7 @@ const int WEP_TYPE_MELEE_PRI      = 0x400; // primary attack is melee swing (for
 const int WEP_TYPE_MELEE_SEC      = 0x800; // secondary attack is melee swing (for animation)
 const int WEP_FLAG_DUALWIELD      = 0x1000; // weapon can be dual wielded
 const int WEP_FLAG_NODUAL         = 0x2000; // weapon doesn't work well with dual wielding (fireball etc just explode on fire), doesn't currently prevent anything
+const int WEP_FLAG_PENETRATEWALLS = 0x4000; // weapon has high calibur bullets that can penetrate thick walls (WEAPONTODO)
 
 // variables:
 string weaponorder_byid;
index 6e618c8..88d50f8 100644 (file)
@@ -489,14 +489,14 @@ METHOD(Devastator, wr_checkammo1, bool(entity thiswep, entity actor, .entity wea
     #if 0
     if(actor.rl_release == 0)
     {
-        LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE\n", actor.rl_release, actor.(thiswep.ammo_field), WEP_CVAR(devastator, ammo));
+        LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE", actor.rl_release, actor.(thiswep.ammo_field), WEP_CVAR(devastator, ammo));
         return true;
     }
     else
     {
         ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo);
         ammo_amount += actor.(weaponentity).(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo);
-        LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s\n", actor.rl_release, actor.(thiswep.ammo_field), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE"));
+        LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s", actor.rl_release, actor.(thiswep.ammo_field), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE"));
         return ammo_amount;
     }
     #else
index 66a7cb6..5cd912a 100644 (file)
@@ -3,7 +3,7 @@
 CLASS(MachineGun, Weapon)
 /* ammotype  */ ATTRIB(MachineGun, ammo_field, .int, ammo_nails);
 /* impulse   */ ATTRIB(MachineGun, impulse, int, 3);
-/* flags     */ ATTRIB(MachineGun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN);
+/* flags     */ ATTRIB(MachineGun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS);
 /* rating    */ ATTRIB(MachineGun, bot_pickupbasevalue, float, 7000);
 /* color     */ ATTRIB(MachineGun, wpcolor, vector, '1 1 0');
 /* modelname */ ATTRIB(MachineGun, mdl, string, "uzi");
index 29520f5..ed5496f 100644 (file)
@@ -3,7 +3,7 @@
 CLASS(Rifle, Weapon)
 /* ammotype  */ ATTRIB(Rifle, ammo_field, .int, ammo_nails);
 /* impulse   */ ATTRIB(Rifle, impulse, int, 7);
-/* flags     */ ATTRIB(Rifle, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN);
+/* flags     */ ATTRIB(Rifle, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS);
 /* rating    */ ATTRIB(Rifle, bot_pickupbasevalue, float, 7000);
 /* color     */ ATTRIB(Rifle, wpcolor, vector, '0.5 1 0');
 /* modelname */ ATTRIB(Rifle, mdl, string, "campingrifle");
index b190cce..bc9e947 100644 (file)
@@ -110,14 +110,14 @@ void W_Shockwave_Melee_Think(entity this)
                                { accuracy_add(this.realowner, WEP_SHOCKWAVE.m_id, 0, swing_damage); }
 
                        #ifdef DEBUG_SHOCKWAVE
-                       LOG_INFO(sprintf(
-                               "MELEE: %s hitting %s with %f damage (factor: %f) at %f time.\n",
+                       LOG_INFOF(
+                               "MELEE: %s hitting %s with %f damage (factor: %f) at %f time.",
                                this.realowner.netname,
                                target_victim.netname,
                                swing_damage,
                                swing_factor,
                                time
-                       ));
+                       );
                        #endif
 
                        // allow multiple hits with one swing, but not against the same player twice
@@ -397,15 +397,15 @@ void W_Shockwave_Attack(entity actor, .entity weaponentity)
                                );
 
                                #ifdef DEBUG_SHOCKWAVE
-                               LOG_INFO(sprintf(
+                               LOG_INFOF(
                                        "SELF HIT: multiplier = %f, damage = %f, force = %f... "
-                                       "multiplier_from_accuracy = %f, multiplier_from_distance = %f.\n",
+                                       "multiplier_from_accuracy = %f, multiplier_from_distance = %f.",
                                        multiplier,
                                        final_damage,
                                        vlen(final_force),
                                        multiplier_from_accuracy,
                                        multiplier_from_distance
-                               ));
+                               );
                                #endif
                        }
                        else if(distance_to_head <= WEP_CVAR(shockwave, blast_splash_radius))
@@ -460,15 +460,15 @@ void W_Shockwave_Attack(entity actor, .entity weaponentity)
                                if(W_Shockwave_Attack_CheckHit(queue, head, final_force, final_damage)) { queue = min(queue + 1, MAX_SHOCKWAVE_HITS); }
 
                                #ifdef DEBUG_SHOCKWAVE
-                               LOG_INFO(sprintf(
+                               LOG_INFOF(
                                        "SPLASH HIT: multiplier = %f, damage = %f, force = %f... "
-                                       "multiplier_from_accuracy = %f, multiplier_from_distance = %f.\n",
+                                       "multiplier_from_accuracy = %f, multiplier_from_distance = %f.",
                                        multiplier,
                                        final_damage,
                                        vlen(final_force),
                                        multiplier_from_accuracy,
                                        multiplier_from_distance
-                               ));
+                               );
                                #endif
                        }
                }
@@ -549,15 +549,15 @@ void W_Shockwave_Attack(entity actor, .entity weaponentity)
                                if(W_Shockwave_Attack_CheckHit(queue, head, final_force, final_damage)) { queue = min(queue + 1, MAX_SHOCKWAVE_HITS); }
 
                                #ifdef DEBUG_SHOCKWAVE
-                               LOG_INFO(sprintf(
+                               LOG_INFOF(
                                        "BLAST HIT: multiplier = %f, damage = %f, force = %f... "
-                                       "multiplier_from_accuracy = %f, multiplier_from_distance = %f.\n",
+                                       "multiplier_from_accuracy = %f, multiplier_from_distance = %f.",
                                        multiplier,
                                        final_damage,
                                        vlen(final_force),
                                        multiplier_from_accuracy,
                                        multiplier_from_distance
-                               ));