]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'Lyberta/KillSound' into 'master'
authorMirio <opivy@hotmail.de>
Wed, 25 Apr 2018 15:43:36 +0000 (15:43 +0000)
committerMirio <opivy@hotmail.de>
Wed, 25 Apr 2018 15:43:36 +0000 (15:43 +0000)
New kill sound.

See merge request xonotic/xonotic-data.pk3dir!431

232 files changed:
.gitlab-ci.yml
.tx/merge-base
cmake/qcc.sh
common.kw.po
common.pl.po
common.pt.po
mutators.cfg
qcsrc/client/bgmscript.qc
qcsrc/client/bgmscript.qh
qcsrc/client/commands/cl_cmd.qc
qcsrc/client/hud/hud.qc
qcsrc/client/hud/hud.qh
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/chat.qc
qcsrc/client/hud/panel/modicons.qc
qcsrc/client/hud/panel/quickmenu.qc
qcsrc/client/hud/panel/radar.qc
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/hud/panel/vote.qc
qcsrc/client/hud/panel/weapons.qc
qcsrc/client/main.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/mutators/events.qh
qcsrc/client/player_skeleton.qc
qcsrc/client/player_skeleton.qh
qcsrc/client/shownames.qh
qcsrc/client/teamradar.qh
qcsrc/client/view.qc
qcsrc/client/wall.qc
qcsrc/client/wall.qh
qcsrc/client/weapons/projectile.qh
qcsrc/common/campaign_file.qc
qcsrc/common/debug.qh
qcsrc/common/effects/effectinfo.qc
qcsrc/common/effects/qc/casings.qc
qcsrc/common/effects/qc/globalsound.qc
qcsrc/common/effects/qc/modeleffects.qc
qcsrc/common/effects/qc/rubble.qh
qcsrc/common/ent_cs.qc
qcsrc/common/minigames/minigame/bd.qc
qcsrc/common/minigames/minigame/c4.qc
qcsrc/common/minigames/minigame/nmm.qc
qcsrc/common/minigames/minigame/pp.qc
qcsrc/common/minigames/minigame/ps.qc
qcsrc/common/minigames/minigame/ttt.qc
qcsrc/common/minigames/sv_minigames.qc
qcsrc/common/models/model.qh
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/monsters/sv_spawn.qc
qcsrc/common/mutators/base.qh
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
qcsrc/common/mutators/mutator/cloaked/sv_cloaked.qc
qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc
qcsrc/common/mutators/mutator/melee_only/sv_melee_only.qc
qcsrc/common/mutators/mutator/new_toys/sv_new_toys.qc
qcsrc/common/mutators/mutator/nix/sv_nix.qc
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/pinata/sv_pinata.qc
qcsrc/common/mutators/mutator/rocketminsta/sv_rocketminsta.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/mutators/mutator/waypoints/waypointsprites.qh
qcsrc/common/notifications/all.qc
qcsrc/common/physics/player.qc
qcsrc/common/physics/player.qh
qcsrc/common/playerstats.qc
qcsrc/common/sounds/sound.qh
qcsrc/common/t_items.qc
qcsrc/common/triggers/defs.qh [new file with mode: 0644]
qcsrc/common/triggers/func/bobbing.qc
qcsrc/common/triggers/func/bobbing.qh
qcsrc/common/triggers/func/breakable.qc
qcsrc/common/triggers/func/breakable.qh
qcsrc/common/triggers/func/button.qc
qcsrc/common/triggers/func/button.qh
qcsrc/common/triggers/func/conveyor.qc
qcsrc/common/triggers/func/conveyor.qh
qcsrc/common/triggers/func/door.qc
qcsrc/common/triggers/func/door.qh
qcsrc/common/triggers/func/door_rotating.qc
qcsrc/common/triggers/func/door_rotating.qh
qcsrc/common/triggers/func/door_secret.qc
qcsrc/common/triggers/func/door_secret.qh
qcsrc/common/triggers/func/ladder.qc
qcsrc/common/triggers/func/plat.qc
qcsrc/common/triggers/func/pointparticles.qc
qcsrc/common/triggers/func/pointparticles.qh
qcsrc/common/triggers/func/rainsnow.qc
qcsrc/common/triggers/func/rainsnow.qh
qcsrc/common/triggers/func/rotating.qc
qcsrc/common/triggers/func/rotating.qh
qcsrc/common/triggers/func/train.qc
qcsrc/common/triggers/func/train.qh
qcsrc/common/triggers/func/vectormamamam.qc
qcsrc/common/triggers/func/vectormamamam.qh
qcsrc/common/triggers/misc/corner.qc
qcsrc/common/triggers/misc/follow.qc
qcsrc/common/triggers/misc/follow.qh
qcsrc/common/triggers/misc/laser.qc
qcsrc/common/triggers/misc/laser.qh
qcsrc/common/triggers/misc/teleport_dest.qc
qcsrc/common/triggers/platforms.qc
qcsrc/common/triggers/platforms.qh
qcsrc/common/triggers/subs.qc
qcsrc/common/triggers/subs.qh
qcsrc/common/triggers/target/changelevel.qc
qcsrc/common/triggers/target/changelevel.qh
qcsrc/common/triggers/target/levelwarp.qc
qcsrc/common/triggers/target/music.qc
qcsrc/common/triggers/target/music.qh
qcsrc/common/triggers/target/spawn.qc
qcsrc/common/triggers/target/speaker.qc
qcsrc/common/triggers/target/speaker.qh
qcsrc/common/triggers/teleporters.qh
qcsrc/common/triggers/trigger/counter.qc
qcsrc/common/triggers/trigger/counter.qh
qcsrc/common/triggers/trigger/flipflop.qc
qcsrc/common/triggers/trigger/gravity.qc
qcsrc/common/triggers/trigger/gravity.qh
qcsrc/common/triggers/trigger/heal.qc
qcsrc/common/triggers/trigger/heal.qh
qcsrc/common/triggers/trigger/hurt.qc
qcsrc/common/triggers/trigger/impulse.qc
qcsrc/common/triggers/trigger/impulse.qh
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/triggers/trigger/jumppads.qh
qcsrc/common/triggers/trigger/keylock.qc
qcsrc/common/triggers/trigger/magicear.qc
qcsrc/common/triggers/trigger/magicear.qh
qcsrc/common/triggers/trigger/monoflop.qc
qcsrc/common/triggers/trigger/monoflop.qh
qcsrc/common/triggers/trigger/multi.qc
qcsrc/common/triggers/trigger/multivibrator.qc
qcsrc/common/triggers/trigger/relay.qc
qcsrc/common/triggers/trigger/relay_activators.qc
qcsrc/common/triggers/trigger/relay_if.qc
qcsrc/common/triggers/trigger/relay_if.qh
qcsrc/common/triggers/trigger/relay_teamcheck.qc
qcsrc/common/triggers/trigger/relay_teamcheck.qh
qcsrc/common/triggers/trigger/teleport.qc
qcsrc/common/triggers/trigger/viewloc.qc
qcsrc/common/triggers/trigger/viewloc.qh
qcsrc/common/triggers/triggers.qc
qcsrc/common/triggers/triggers.qh
qcsrc/common/turrets/turret/plasma.qc
qcsrc/common/turrets/turret/plasma_dual.qc
qcsrc/common/util.qc
qcsrc/common/weapons/weapon/hook.qc
qcsrc/common/weapons/weapon/tuba.qh
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/ecs/systems/physics.qc
qcsrc/ecs/systems/sv_physics.qc
qcsrc/lib/_all.inc
qcsrc/lib/accumulate.qh
qcsrc/lib/compiler.qh
qcsrc/lib/cvar.qh
qcsrc/lib/defer.qh
qcsrc/lib/matrix/command.qc
qcsrc/lib/matrix/matrix.qc
qcsrc/lib/misc.qh
qcsrc/lib/net.qh
qcsrc/lib/noise.qh
qcsrc/lib/oo.qh
qcsrc/lib/registry.qh
qcsrc/lib/replicate.qh
qcsrc/lib/self.qh
qcsrc/lib/sortlist.qh
qcsrc/lib/spawnfunc.qh
qcsrc/lib/static.qh
qcsrc/lib/stats.qh
qcsrc/lib/string.qh
qcsrc/lib/test.qh
qcsrc/lib/urllib.qc
qcsrc/lib/warpzone/mathlib.qc
qcsrc/menu/item/inputbox.qc
qcsrc/menu/item/label.qc
qcsrc/menu/menu.qc
qcsrc/menu/mutators/events.qh
qcsrc/menu/xonotic/campaign.qc
qcsrc/menu/xonotic/crosshairpreview.qc
qcsrc/menu/xonotic/cvarlist.qc
qcsrc/menu/xonotic/demolist.qc
qcsrc/menu/xonotic/dialog_multiplayer_create.qc
qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc
qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc
qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc
qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc
qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc
qcsrc/menu/xonotic/hudskinlist.qc
qcsrc/menu/xonotic/keybinder.qc
qcsrc/menu/xonotic/maplist.qc
qcsrc/menu/xonotic/playermodel.qc
qcsrc/menu/xonotic/screenshotimage.qc
qcsrc/menu/xonotic/screenshotlist.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/serverlist.qh
qcsrc/menu/xonotic/soundlist.qc
qcsrc/menu/xonotic/util.qc
qcsrc/menu/xonotic/weaponarenacheckbox.qc
qcsrc/server/autocvars.qh
qcsrc/server/bot/default/bot.qc
qcsrc/server/bot/default/scripting.qc
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/bot/default/waypoints.qh
qcsrc/server/campaign.qc
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/command/cmd.qc
qcsrc/server/command/common.qc
qcsrc/server/command/vote.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_models.qc
qcsrc/server/g_world.qc
qcsrc/server/ipban.qc
qcsrc/server/mapvoting.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/events.qh
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_cts.qc
qcsrc/server/mutators/mutator/gamemode_race.qc
qcsrc/server/race.qc
qcsrc/server/resources.qc
qcsrc/server/scores.qc
qcsrc/server/sv_main.qc
qcsrc/server/teamplay.qc
qcsrc/server/weapons/weaponsystem.qc
ruleset-nexuiz.cfg [new file with mode: 0644]
xonotic-server.cfg

index 4754425bf971689d6df0aaf9cfdad7f13dcd7595..12c3686e76ce1fc8d5b4da57d7e874fe9ec1d0db 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=fb771b180a47f7acf09eb12dddd391f8
+    - EXPECT=b879b7f0d2da1b120211eabde0caab72
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index 431dcbe974dc57728a788a275a92bcbc985444ca..53527f3c728703d8d1aa6e9f5fc126198c7d0dbf 100644 (file)
@@ -1 +1 @@
-Sat Mar 17 07:23:46 CET 2018
+Fri Apr 20 07:23:54 CEST 2018
index 78119a59615bf0dfdabf5473c4f374ce76519bda..a6038dd59131c5df736e0862c8b29086f6833162 100755 (executable)
@@ -3,7 +3,16 @@ CPP=${CPP:-cpp}
 QCC=${QCC:-$PWD/../../gmqcc/gmqcc${CMAKE_EXECUTABLE_SUFFIX}}
 case $1 in
     compile)
-        ${CPP} ${@:3} | sed -E 's/^#(line)? ([[:digit:]]+) "(.*)".*/'$'\\\n''#pragma file(\3)'$'\\\n''#pragma line(\2)/g' > $2
+        for var in "$@"; do case "$var" in
+            -I*)
+                home=${var:2}
+                break
+                ;;
+        esac; done
+        ${CPP} ${@:3} \
+            | sed -E "s|${home}|~|g" \
+            | sed -E 's/^#(line)? ([[:digit:]]+) "(.*)".*/'$'\\\n''#pragma file(\3)'$'\\\n''#pragma line(\2)/g' \
+            > $2
     ;;
     link)
         ${QCC} \
index 33fbaf5be42b6257b4e7a8dd963119c9d8036ff7..9c550db7c1d0f57b30022d4c1c18f8bab346812f 100644 (file)
@@ -3,7 +3,8 @@
 # This file is distributed under the same license as the PACKAGE package.
 #
 # Translators:
-# Nicky Rowe <nickyrowe@gmail.com>, 2016
+# Nicky Rowe <nickyrowe688@gmail.com>, 2016
+# Nicky Rowe <nickyrowe688@gmail.com>, 2016
 msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
index f8c5ab3bb4e145ab0637ed0f6d8413168984aa90..0b40453da5c9aa0dc5cfe785e3add14ea5e6ba47 100644 (file)
 # Kriss Chr <kriss7475@gmail.com>, 2017
 # Piotr Kozica <koza91@gmail.com>, 2016
 # RafaÅ‚ SzymaÅ„ski <okavasly@gmail.com>, 2017
-# Robert Wolniak <robert.wolniak@gmail.com>, 2015
+# Robert Wolniak <robert.wolniak@gmail.com>, 2015,2018
 # Sertomas, 2014
 msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-07-09 00:35+0200\n"
-"PO-Revision-Date: 2017-09-20 00:10+0000\n"
-"Last-Translator: RafaÅ‚ SzymaÅ„ski <okavasly@gmail.com>\n"
+"PO-Revision-Date: 2018-04-19 09:01+0000\n"
+"Last-Translator: Robert Wolniak <robert.wolniak@gmail.com>\n"
 "Language-Team: Polish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/pl/)\n"
 "Language: pl\n"
@@ -1158,7 +1158,7 @@ msgstr ""
 
 #: qcsrc/common/gamemodes/gamemode/nexball/weapon.qh:7
 msgid "Ball Stealer"
-msgstr ""
+msgstr "ZÅ‚odziej Kuli"
 
 #: qcsrc/common/items/item/armor.qh:111
 msgid "Big armor"
@@ -1310,6 +1310,8 @@ msgid ""
 "Kill enemies to freeze them, stand next to frozen teammates to revive them; "
 "freeze all enemies to win"
 msgstr ""
+"Zabijaj przeciwników by ich zamrozić i stój obok czÅ‚onków swojej drużyny by "
+"ich wskrzesić; aby wygrać, zamroź wszystkich wrogów"
 
 #: qcsrc/common/mapinfo.qh:446
 msgid "Hold the ball to get points for kills"
@@ -1468,6 +1470,8 @@ msgid ""
 "You lost the game!\n"
 "Select \"^1Next Match^7\" on the menu for a rematch!"
 msgstr ""
+"Przegrana meczu!\n"
+"Wybierz w menu opcjÄ™ \"^1NastÄ™pny Mecz^7\" po rewanż!"
 
 #: qcsrc/common/minigames/minigame/pp.qc:444
 #: qcsrc/common/minigames/minigame/ttt.qc:325
@@ -1475,16 +1479,18 @@ msgid ""
 "You win!\n"
 "Select \"^1Next Match^7\" on the menu to start a new match!"
 msgstr ""
+"Wygrana!\n"
+"Wybierz w menu opcjÄ™ \"^1NastÄ™pny Mecz^7\" by rozpocząć nowÄ… grÄ™!"
 
 #: qcsrc/common/minigames/minigame/pp.qc:450
 #: qcsrc/common/minigames/minigame/ttt.qc:331
 msgid "Select \"^1Next Match^7\" on the menu to start a new match!"
-msgstr ""
+msgstr "Wybierz w menu opcjÄ™ \"^1NastÄ™pny Mecz^7\" by rozpocząć nowÄ… grÄ™!"
 
 #: qcsrc/common/minigames/minigame/pp.qc:451
 #: qcsrc/common/minigames/minigame/ttt.qc:332
 msgid "Wait for your opponent to confirm the rematch"
-msgstr ""
+msgstr "Poczekaj aż twój przeciwnik potwierdzi rewanż."
 
 #: qcsrc/common/minigames/minigame/pp.qc:582
 #: qcsrc/common/minigames/minigame/ttt.qc:665
index ec526d5e35b64187d305a117a1b2087a16b86cc5..c7f46b867abaea8e99456dd866004e98d4522777 100644 (file)
@@ -4,7 +4,7 @@
 #
 # Translators:
 # Ivan Paulos Tomé <greylica@gmail.com>, 2016
-# Jean Trindade Pereira <jean_trindade2@hotmail.com>, 2015-2017
+# Jean Trindade Pereira <jean_trindade2@hotmail.com>, 2015-2018
 # Mirio <opivy@hotmail.de>, 2017
 # NotThatPrivate Yes <henriqueferreira2009@gmail.com>, 2015
 # Ricardo Manuel da Cruz Coelho da Silva <ricardo.mccs@gmail.com>, 2015
@@ -13,7 +13,7 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-07-09 00:35+0200\n"
-"PO-Revision-Date: 2017-12-21 15:23+0000\n"
+"PO-Revision-Date: 2018-04-17 20:43+0000\n"
 "Last-Translator: Jean Trindade Pereira <jean_trindade2@hotmail.com>\n"
 "Language-Team: Portuguese (http://www.transifex.com/team-xonotic/xonotic/"
 "language/pt/)\n"
@@ -765,16 +765,16 @@ msgid ""
 "^3caps^7                     How often a flag (CTF) or a key (KeyHunt) was "
 "captured\n"
 msgstr ""
-"^3capturas^7 Quão frequente uma bandeira (CTF) ou uma chave (KeyHunt) foi "
-"capturada\n"
+"^3capturas^7 Quão frequente uma bandeira (CTF) ou uma chave (Caça a Chaves) "
+"foi capturada\n"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:317
 msgid ""
 "^3pickups^7                  How often a flag (CTF) or a key (KeyHunt) or a "
 "ball (Keepaway) was picked up\n"
 msgstr ""
-"^3coletas^7. Quão frequente uma bandeira (CTF), uma chave (KeyHunt) ou uma "
-"bola (Keepaway) foi coletada\n"
+"^3coletas^7. Quão frequente uma bandeira (CTF), uma chave (Caça a Chaves) ou "
+"uma bola (Keepaway) foi coletada\n"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:318
 msgid "^3captime^7                  Time of fastest cap (CTF)\n"
@@ -1207,7 +1207,7 @@ msgstr "Consiga o máximo de execuções que puder"
 
 #: qcsrc/common/mapinfo.qh:111
 msgid "Last Man Standing"
-msgstr "Last Man Standing"
+msgstr "Último Homem de Pé"
 
 #: qcsrc/common/mapinfo.qh:111
 msgid "Survive and kill until the enemies have no lives left"
@@ -1251,7 +1251,7 @@ msgstr ""
 
 #: qcsrc/common/mapinfo.qh:249
 msgid "Clan Arena"
-msgstr "Clan Arena"
+msgstr "Clã Arena"
 
 #: qcsrc/common/mapinfo.qh:249
 msgid "Kill all enemy teammates to win the round"
@@ -1263,7 +1263,7 @@ msgstr "Capture e defenda todos os pontos de controle para vencer"
 
 #: qcsrc/common/mapinfo.qh:287
 msgid "Domination"
-msgstr "Domination"
+msgstr "Dominação"
 
 #: qcsrc/common/mapinfo.qh:319
 msgid "Gather all the keys to win the round"
@@ -1271,11 +1271,11 @@ msgstr "Colete todas as chaves para vencer a rodada"
 
 #: qcsrc/common/mapinfo.qh:319
 msgid "Key Hunt"
-msgstr "Key Hunt"
+msgstr "Caça a Chaves"
 
 #: qcsrc/common/mapinfo.qh:353
 msgid "Assault"
-msgstr "Assault"
+msgstr "Assalto"
 
 #: qcsrc/common/mapinfo.qh:353
 msgid ""
@@ -1291,11 +1291,11 @@ msgstr "Capture pontos de controle para alcançar e destruir o gerador inimigo"
 
 #: qcsrc/common/mapinfo.qh:371
 msgid "Onslaught"
-msgstr "Onslaught"
+msgstr "Massacre"
 
 #: qcsrc/common/mapinfo.qh:387
 msgid "Nexball"
-msgstr "Nexball"
+msgstr "Bola Nex"
 
 #: qcsrc/common/mapinfo.qh:387
 msgid "Shoot and kick the ball into the enemies goal, keep your goal clean"
@@ -1303,7 +1303,7 @@ msgstr "Atire e chute a bola no gol inimigo e mantenha seu gol limpo"
 
 #: qcsrc/common/mapinfo.qh:408
 msgid "Freeze Tag"
-msgstr "Freeze Tag"
+msgstr "Congela"
 
 #: qcsrc/common/mapinfo.qh:408
 msgid ""
@@ -1323,7 +1323,7 @@ msgstr "Keepaway"
 
 #: qcsrc/common/mapinfo.qh:461
 msgid "Invasion"
-msgstr "Invasion"
+msgstr "Invasão"
 
 #: qcsrc/common/mapinfo.qh:461
 msgid "Survive against waves of monsters"
@@ -5217,7 +5217,7 @@ msgstr "Tempo de desaparecimento:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:25
 msgid "Flip messages order"
-msgstr "Trocar ordem de notificações"
+msgstr "Trocar ordem de mensagens"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:27
 #: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:15
@@ -5704,7 +5704,7 @@ msgstr "Exibir munições"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:68
 msgid "Ammo bar alpha:"
-msgstr "Cor da barra de munições:"
+msgstr "Transparência da barra de munições:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:74
 msgid "Ammo bar color:"
@@ -6327,7 +6327,7 @@ msgstr "Modificadores de armas e itens:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:204
 msgid "Grappling hook"
-msgstr "Gancho (grappling hook)"
+msgstr "Gancho de escalada"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:205
 msgid "Players spawn with the grappling hook"
index 32145dd04c8128f7e65b24d7a0c752d2d9b6cc7c..c997a807f459574846fc3de6b11af14ddbe7447b 100644 (file)
@@ -276,7 +276,7 @@ set g_nades_entrap_radius 500
 
 // Veil (9)
 set g_nades_veil_time 8 "Life time of the orb"
-set g_nades_veil_radius 300
+set g_nades_veil_radius 200
 
 
 // ============
index 2db9e54cf1af01dfd8bf9e0348a204f11d9e4f47..02739194a858b799752f06dca40e36b8aade1bae 100644 (file)
@@ -11,12 +11,12 @@ float bgmscriptbuf;
 float bgmscriptbufsize;
 float bgmscriptbufloaded;
 
-class(BGMScript) .float bgmscriptline;
-class(BGMScript) .float bgmscriptline0;
-class(BGMScript) .float bgmscriptvolume;
-class(BGMScript) .float bgmscripttime;
-class(BGMScript) .float bgmscriptstate;
-class(BGMScript) .float bgmscriptstatetime;
+classfield(BGMScript) .float bgmscriptline;
+classfield(BGMScript) .float bgmscriptline0;
+classfield(BGMScript) .float bgmscriptvolume;
+classfield(BGMScript) .float bgmscripttime;
+classfield(BGMScript) .float bgmscriptstate;
+classfield(BGMScript) .float bgmscriptstatetime;
 
 float GetAttackDecaySustainAmplitude(float a, float d, float s, float t)
 {
@@ -139,8 +139,7 @@ void BGMScript_InitEntity(entity e)
                if(i >= bgmscriptbufsize)
                {
                        LOG_INFOF("ERROR: bgmscript does not define %s", e.bgmscript);
-                       strunzone(e.bgmscript);
-                       e.bgmscript = string_null;
+                       strfree(e.bgmscript);
                }
        }
 }
index 18b0d5ee4231c5c9e95998fdad5be86331b0b1e8..a3044d537cd3200bedd070f38be867b801456e9e 100644 (file)
@@ -1,13 +1,13 @@
 #pragma once
 
 entityclass(BGMScript);
-class(BGMScript) .string bgmscript;
-class(BGMScript) .float bgmscriptattack;
-class(BGMScript) .float bgmscriptdecay;
-class(BGMScript) .float bgmscriptsustain;
-class(BGMScript) .float bgmscriptrelease;
+classfield(BGMScript) .string bgmscript;
+classfield(BGMScript) .float bgmscriptattack;
+classfield(BGMScript) .float bgmscriptdecay;
+classfield(BGMScript) .float bgmscriptsustain;
+classfield(BGMScript) .float bgmscriptrelease;
 
-class(BGMScript) .float just_toggled;
+classfield(BGMScript) .float just_toggled;
 
 #ifdef CSQC
 void BGMScript_InitEntity(entity e);
index 8faf0f387b6ccd33103cbfd825dec2692a7ac760..8eea240d40f4da8ebdd79bb9dee4a30b364e19b2 100644 (file)
@@ -418,7 +418,7 @@ void LocalCommand_sendcvar(int request, int argc)
                        if (argv(1))
                        {
                                // W_FixWeaponOrder will trash argv, so save what we need.
-                               string thiscvar = strzone(argv(1));
+                               string thiscvar = string_null; strcpy(thiscvar, argv(1));
                                string s = cvar_string(thiscvar);
 
                                if (thiscvar == "cl_weaponpriority")
@@ -427,7 +427,7 @@ void LocalCommand_sendcvar(int request, int argc)
                                        s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0);
 
                                localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n");
-                               strunzone(thiscvar);
+                               strfree(thiscvar);
                                return;
                        }
                }
index 9bcdd3d6624422a18a245423dc2f44589d6a090c..01799caccc7d307e5c99daabde9263750e24b232 100644 (file)
@@ -579,12 +579,8 @@ void HUD_Main()
        // Drawing stuff
        if (hud_skin_prev != autocvar_hud_skin)
        {
-               if (hud_skin_path)
-                       strunzone(hud_skin_path);
-               hud_skin_path = strzone(strcat("gfx/hud/", autocvar_hud_skin));
-               if (hud_skin_prev)
-                       strunzone(hud_skin_prev);
-               hud_skin_prev = strzone(autocvar_hud_skin);
+               strcpy(hud_skin_path, strcat("gfx/hud/", autocvar_hud_skin));
+               strcpy(hud_skin_prev, autocvar_hud_skin);
        }
 
        // draw the dock
@@ -659,9 +655,7 @@ void HUD_Main()
                        LOG_TRACE("Automatically fixed wrong/missing panel numbers in _hud_panelorder");
 
                cvar_set("_hud_panelorder", s);
-               if(hud_panelorder_prev)
-                       strunzone(hud_panelorder_prev);
-               hud_panelorder_prev = strzone(s);
+               strcpy(hud_panelorder_prev, s);
 
                //now properly set panel_order
                tokenize_console(s);
index d070dce380d3b4877f5ac6457a9993a388717957..496d775efe4f3ad39c0a1a26196753bfb089b82a 100644 (file)
@@ -120,18 +120,18 @@ vector panel_size_copied;
 
 entity panel;
 entityclass(HUDPanel);
-class(HUDPanel) .string panel_name;
-class(HUDPanel) .int panel_id;
-class(HUDPanel) .vector current_panel_pos;
-class(HUDPanel) .vector current_panel_size;
-class(HUDPanel) .string current_panel_bg;
-class(HUDPanel) .float current_panel_bg_alpha;
-class(HUDPanel) .float current_panel_bg_border;
-class(HUDPanel) .vector current_panel_bg_color;
-class(HUDPanel) .float current_panel_bg_color_team;
-class(HUDPanel) .float current_panel_bg_padding;
-class(HUDPanel) .float current_panel_fg_alpha;
-class(HUDPanel) .float update_time;
+classfield(HUDPanel) .string panel_name;
+classfield(HUDPanel) .int panel_id;
+classfield(HUDPanel) .vector current_panel_pos;
+classfield(HUDPanel) .vector current_panel_size;
+classfield(HUDPanel) .string current_panel_bg;
+classfield(HUDPanel) .float current_panel_bg_alpha;
+classfield(HUDPanel) .float current_panel_bg_border;
+classfield(HUDPanel) .vector current_panel_bg_color;
+classfield(HUDPanel) .float current_panel_bg_color_team;
+classfield(HUDPanel) .float current_panel_bg_padding;
+classfield(HUDPanel) .float current_panel_fg_alpha;
+classfield(HUDPanel) .float update_time;
 float panel_enabled;
 vector panel_pos;
 vector panel_size;
@@ -148,7 +148,7 @@ string panel_bg_border_str;
 float panel_bg_padding;
 string panel_bg_padding_str;
 
-class(HUDPanel) .void() panel_draw;
+classfield(HUDPanel) .void() panel_draw;
 
 // chat panel can be reduced / moved while the mapvote is active
 // let know the mapvote panel about chat pos and size
@@ -264,9 +264,7 @@ REGISTER_HUD_PANEL(SCOREBOARD,      Scoreboard_Draw,    PANEL_CONFIG_NO
                        }                                                                                                       \
                }                                                                                                           \
        }                                                                                                               \
-       if (panel.current_panel_bg)                                                                                     \
-               strunzone(panel.current_panel_bg);                                                                          \
-       panel.current_panel_bg = strzone(panel_bg);                                                                     \
+       strcpy(panel.current_panel_bg, panel_bg);                                                                       \
 } MACRO_END
 
 // Get value for panel_bg_color: if "" fetch default, else use panel_bg_color. Convert pants, shirt or teamcolor into a vector.
index ec07ee4095a30e3c1c462f25fae034882e87b123..3c93a6d64ca1b5723817c94eaa4287a16c28e745 100644 (file)
@@ -1029,9 +1029,7 @@ void HUD_Panel_FirstInDrawQ(float id)
                s = strcat(s, ftos(panel_order[i]), " ");
        }
        cvar_set("_hud_panelorder", s);
-       if(hud_panelorder_prev)
-               strunzone(hud_panelorder_prev);
-       hud_panelorder_prev = strzone(autocvar__hud_panelorder); // prevent HUD_Main from doing useless update, we already updated here
+       strcpy(hud_panelorder_prev, autocvar__hud_panelorder); // prevent HUD_Main from doing useless update, we already updated here
 }
 
 void HUD_Panel_Highlight(float allow_move)
index a92bdc69234a1dac1f90762cd8a74243f986c17d..f8f70c8189e671de3cb01fd3d4c4a8aab3e7745a 100644 (file)
@@ -75,9 +75,7 @@ void centerprint_generic(int new_id, string strMessage, float duration, int coun
                        cpm_index = CENTERPRINT_MAX_MSGS - 1;
                j = cpm_index;
        }
-       if(centerprint_messages[j])
-               strunzone(centerprint_messages[j]);
-       centerprint_messages[j] = strzone(strMessage);
+       strcpy(centerprint_messages[j], strMessage);
        centerprint_msgID[j] = new_id;
        if (duration < 0)
        {
@@ -112,9 +110,7 @@ void reset_centerprint_messages()
                centerprint_expire_time[i] = 0;
                centerprint_time[i] = 1;
                centerprint_msgID[i] = 0;
-               if(centerprint_messages[i])
-                       strunzone(centerprint_messages[i]);
-               centerprint_messages[i] = string_null;
+               strfree(centerprint_messages[i]);
        }
 }
 float hud_configure_cp_generation_time;
index 74d4b6d0f49462f522298e276770244dc54e278a..5f309d0b0224bd4c019f9f4d51b29a9f851368a9 100644 (file)
@@ -48,9 +48,7 @@ void HUD_Chat()
                        panel_bg = strcat(hud_skin_path, "/border_default");
                        if(precache_pic(panel_bg) == "")
                                panel_bg = "gfx/hud/default/border_default";
-                       if(panel.current_panel_bg)
-                               strunzone(panel.current_panel_bg);
-                       panel.current_panel_bg = strzone(panel_bg);
+                       strcpy(panel.current_panel_bg, panel_bg);
                        chat_panel_modified = true;
                }
                panel_bg_alpha = max(0.75, panel_bg_alpha);
index 65682b3ec7d27006a653449ad69e7b725ba69516..0bbcb41484a85db250f8655e03ec4f16149c1b10 100644 (file)
@@ -583,9 +583,7 @@ void HUD_Mod_Race(vector pos, vector mySize)
        if (race_status != race_status_prev || race_status_name != race_status_name_prev) {
                race_status_time = time + 5;
                race_status_prev = race_status;
-               if (race_status_name_prev)
-                       strunzone(race_status_name_prev);
-               race_status_name_prev = strzone(race_status_name);
+               strcpy(race_status_name_prev, race_status_name);
        }
 
        // race "awards"
@@ -621,12 +619,8 @@ void HUD_Mod_Race(vector pos, vector mySize)
        if (race_status_time - time <= 0) {
                race_status_prev = -1;
                race_status = -1;
-               if(race_status_name)
-                       strunzone(race_status_name);
-               race_status_name = string_null;
-               if(race_status_name_prev)
-                       strunzone(race_status_name_prev);
-               race_status_name_prev = string_null;
+               strfree(race_status_name);
+               strfree(race_status_name_prev);
        }
 }
 
index ba3e5f0cb50374882c2d864dc780ca54eba83d90..b84066b84f4de86723d9944b6de302d2711e23f3 100644 (file)
@@ -45,23 +45,15 @@ void QuickMenu_Page_LoadEntry(int i, string s, string s1)
 {
     TC(int, i);
        //LOG_INFOF("^xc80 entry %d: %s, %s\n", i, s, s1);
-       if (QuickMenu_Page_Description[i])
-               strunzone(QuickMenu_Page_Description[i]);
-       QuickMenu_Page_Description[i] = strzone(s);
-       if (QuickMenu_Page_Command[i])
-               strunzone(QuickMenu_Page_Command[i]);
-       QuickMenu_Page_Command[i] = strzone(s1);
+       strcpy(QuickMenu_Page_Description[i], s);
+       strcpy(QuickMenu_Page_Command[i], s1);
 }
 
 void QuickMenu_Page_ClearEntry(int i)
 {
     TC(int, i);
-       if (QuickMenu_Page_Description[i])
-               strunzone(QuickMenu_Page_Description[i]);
-       QuickMenu_Page_Description[i] = string_null;
-       if (QuickMenu_Page_Command[i])
-               strunzone(QuickMenu_Page_Command[i]);
-       QuickMenu_Page_Command[i] = string_null;
+       strfree(QuickMenu_Page_Description[i]);
+       strfree(QuickMenu_Page_Command[i]);
        QuickMenu_Page_Command_Type[i] = 0;
 }
 
@@ -197,9 +189,7 @@ void QuickMenu_Buffer_Close()
 
 void QuickMenu_Close()
 {
-       if (QuickMenu_CurrentSubMenu)
-               strunzone(QuickMenu_CurrentSubMenu);
-       QuickMenu_CurrentSubMenu = string_null;
+       strfree(QuickMenu_CurrentSubMenu);
        int i;
        for (i = 0; i < QUICKMENU_MAXLINES; ++i)
                QuickMenu_Page_ClearEntry(i);
@@ -217,18 +207,17 @@ void QuickMenu_Close()
 // It assumes submenu open tag is already detected
 void QuickMenu_skip_submenu(string submenu)
 {
-       string s, z_submenu;
-       z_submenu = strzone(submenu);
+       string z_submenu = string_null; strcpy(z_submenu, submenu);
        for(++QuickMenu_Buffer_Index ; QuickMenu_Buffer_Index < QuickMenu_Buffer_Size; ++QuickMenu_Buffer_Index)
        {
-               s = QuickMenu_Buffer_Get();
+               string s = QuickMenu_Buffer_Get();
                if(substring(s, 0, 1) != QM_TAG_SUBMENU)
                        continue;
                if(substring(s, 1, -1) == z_submenu) // submenu end
                        break;
                QuickMenu_skip_submenu(substring(s, 1, -1));
        }
-       strunzone(z_submenu);
+       strfree(z_submenu);
 }
 
 bool QuickMenu_IsOpened()
@@ -273,9 +262,7 @@ bool QuickMenu_Page_Load(string target_submenu, bool new_page)
                ++QuickMenu_Page;
 
        z_submenu = strzone(target_submenu);
-       if (QuickMenu_CurrentSubMenu)
-               strunzone(QuickMenu_CurrentSubMenu);
-       QuickMenu_CurrentSubMenu = strzone(z_submenu);
+       strcpy(QuickMenu_CurrentSubMenu, z_submenu);
 
        QuickMenu_IsLastPage = true;
        QuickMenu_Page_Entries = 0;
index b1cc222ccf1a5dab7f70fa08373a41dd184cbe68..f0ec01c9e7b1847e68734896348da82b7658ad0f 100644 (file)
@@ -214,9 +214,7 @@ void HUD_Radar()
                        panel_bg = "gfx/hud/default/border_default"; // fallback
                if(!radar_panel_modified && panel_bg != panel.current_panel_bg)
                        radar_panel_modified = true;
-               if(panel.current_panel_bg)
-                       strunzone(panel.current_panel_bg);
-               panel.current_panel_bg = strzone(panel_bg);
+               strcpy(panel.current_panel_bg, panel_bg);
 
                switch(hud_panel_radar_maximized_zoommode)
                {
index 5e4a31f1e7dce6198f459837f61e62dc954f0c4f..96d30aa52ce8559e6c4cc7dc234d74a44f2e9a99 100644 (file)
@@ -448,8 +448,7 @@ void Cmd_Scoreboard_SetFields(int argc)
                                continue;
                }
 
-               strunzone(sbt_field_title[sbt_num_fields]);
-               sbt_field_title[sbt_num_fields] = strzone(TranslateScoresLabel(str));
+               strcpy(sbt_field_title[sbt_num_fields], TranslateScoresLabel(str));
                sbt_field_size[sbt_num_fields] = stringwidth(sbt_field_title[sbt_num_fields], false, hud_fontsize);
                str = strtolower(str);
 
@@ -540,8 +539,7 @@ LABEL(found)
                }
                else if(!have_separator)
                {
-                       strunzone(sbt_field_title[sbt_num_fields]);
-                       sbt_field_title[sbt_num_fields] = strzone("|");
+                       strcpy(sbt_field_title[sbt_num_fields], "|");
                        sbt_field_size[sbt_num_fields] = stringwidth("|", false, hud_fontsize);
                        sbt_field[sbt_num_fields] = SP_SEPARATOR;
                        ++sbt_num_fields;
@@ -549,8 +547,7 @@ LABEL(found)
                }
                if(!have_secondary)
                {
-                       strunzone(sbt_field_title[sbt_num_fields]);
-                       sbt_field_title[sbt_num_fields] = strzone(TranslateScoresLabel(scores_label(ps_secondary)));
+                       strcpy(sbt_field_title[sbt_num_fields], TranslateScoresLabel(scores_label(ps_secondary)));
                        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;
@@ -558,8 +555,7 @@ LABEL(found)
                }
                if(!have_primary)
                {
-                       strunzone(sbt_field_title[sbt_num_fields]);
-                       sbt_field_title[sbt_num_fields] = strzone(TranslateScoresLabel(scores_label(ps_primary)));
+                       strcpy(sbt_field_title[sbt_num_fields], TranslateScoresLabel(scores_label(ps_primary)));
                        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;
@@ -1489,9 +1485,7 @@ void Scoreboard_Draw()
                        {
                                hud_fontsize = HUD_GetFontsize("hud_fontsize");
                                Scoreboard_initFieldSizes();
-                               if(hud_fontsize_str)
-                                       strunzone(hud_fontsize_str);
-                               hud_fontsize_str = strzone(autocvar_hud_fontsize);
+                               strcpy(hud_fontsize_str, autocvar_hud_fontsize);
                        }
                }
                else {
index 15e18e8f445a2b86f7ed9af851c332a856b99e4c..57b32039dc50fdf401d4da978413c0e4192a800f 100644 (file)
@@ -27,9 +27,7 @@ void HUD_Vote()
                        LOG_INFO(_("^1You must answer before entering hud configure mode"));
                        cvar_set("_hud_configure", "0");
                }
-               if(vote_called_vote)
-                       strunzone(vote_called_vote);
-               vote_called_vote = strzone(_("^2Name ^7instead of \"^1Anonymous player^7\" in stats"));
+               strcpy(vote_called_vote, _("^2Name ^7instead of \"^1Anonymous player^7\" in stats"));
                uid2name_dialog = 1;
        }
 
index 70c4c10131303153faad8ec0fc2bfacb0474265b..4506f69a0c591b603d41ca4fa5f6a497581c071f 100644 (file)
@@ -94,13 +94,8 @@ void HUD_Weapons()
        if(weaponorder_bypriority != autocvar_cl_weaponpriority || !weaponorder[0])
        {
                int weapon_cnt;
-               if(weaponorder_bypriority)
-                       strunzone(weaponorder_bypriority);
-               if(weaponorder_byimpulse)
-                       strunzone(weaponorder_byimpulse);
-
-               weaponorder_bypriority = strzone(autocvar_cl_weaponpriority);
-               weaponorder_byimpulse = strzone(W_FixWeaponOrder_BuildImpulseList(W_FixWeaponOrder_ForceComplete(W_NumberWeaponOrder(weaponorder_bypriority))));
+               strcpy(weaponorder_bypriority, autocvar_cl_weaponpriority);
+               strcpy(weaponorder_byimpulse, W_FixWeaponOrder_BuildImpulseList(W_FixWeaponOrder_ForceComplete(W_NumberWeaponOrder(weaponorder_bypriority))));
                weaponorder_cmp_str = strcat(" ", weaponorder_byimpulse, " ");
 
                weapon_cnt = 0;
index 9c146c09bd9115091c24585fc02c323558b75d19..37027d25cd35570419c819179b207311580f157e 100644 (file)
@@ -555,9 +555,7 @@ NET_HANDLE(ENT_CLIENT_NAGGER, bool isnew)
 
        if(!(nags & BIT(2)))
        {
-               if(vote_called_vote)
-                       strunzone(vote_called_vote);
-               vote_called_vote = string_null;
+               strfree(vote_called_vote);
                vote_active = 0;
        }
        else
@@ -575,9 +573,7 @@ NET_HANDLE(ENT_CLIENT_NAGGER, bool isnew)
 
        if(nags & BIT(7))
        {
-               if(vote_called_vote)
-                       strunzone(vote_called_vote);
-               vote_called_vote = strzone(ReadString());
+               strcpy(vote_called_vote, ReadString());
        }
 
        if(nags & 1)
@@ -959,14 +955,12 @@ NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew)
        teamplay = _MapInfo_GetTeamPlayBool(gametype);
        HUD_ModIcons_SetFunc();
        FOREACH(Scores, true, {
-               if (scores_label(it)) strunzone(scores_label(it));
-               scores_label(it) = strzone(ReadString());
+               strcpy(scores_label(it), ReadString());
                scores_flags(it) = ReadByte();
        });
        for (int i = 0; i < MAX_TEAMSCORE; ++i)
        {
-               if (teamscores_label(i)) strunzone(teamscores_label(i));
-               teamscores_label(i) = strzone(ReadString());
+               strcpy(teamscores_label(i), ReadString());
                teamscores_flags(i) = ReadByte();
        }
        return = true;
@@ -987,8 +981,7 @@ NET_HANDLE(ENT_CLIENT_INIT, bool isnew)
        arc_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
        arc_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
 
-       if (forcefog) strunzone(forcefog);
-       forcefog = strzone(ReadString());
+       strcpy(forcefog, ReadString());
 
        armorblockpercent = ReadByte() / 255.0;
        damagepush_speedfactor = ReadByte() / 255.0;
@@ -1051,17 +1044,15 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_time = ReadInt24_t();
                        race_previousbesttime = ReadInt24_t();
                        race_mypreviousbesttime = ReadInt24_t();
-                       if(race_previousbestname)
-                               strunzone(race_previousbestname);
                        string pbestname = ReadString();
                        if(autocvar_cl_race_cptimes_onlyself)
                        {
                                race_previousbesttime = race_mypreviousbesttime;
                                race_mypreviousbesttime = 0;
-                               race_previousbestname = strzone("");
+                               strcpy(race_previousbestname, "");
                        }
                        else
-                               race_previousbestname = strzone(pbestname);
+                               strcpy(race_previousbestname, pbestname);
 
                        race_checkpointtime = time;
 
@@ -1087,17 +1078,15 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_nextbesttime = ReadInt24_t();
                        if(b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING) // not while spectating (matches server)
                                race_mybesttime = ReadInt24_t();
-                       if(race_nextbestname)
-                               strunzone(race_nextbestname);
                        string newname = ReadString();
                        if(autocvar_cl_race_cptimes_onlyself && b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING)
                        {
                                race_nextbesttime = race_mybesttime;
                                race_mybesttime = 0;
-                               race_nextbestname = strzone("");
+                               strcpy(race_nextbestname, "");
                        }
                        else
-                               race_nextbestname = strzone(newname);
+                               strcpy(race_nextbestname, newname);
                        break;
 
                case RACE_NET_CHECKPOINT_HIT_RACE:
@@ -1107,13 +1096,11 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_mycheckpointlapsdelta = ReadByte();
                        if(race_mycheckpointlapsdelta >= 128)
                                race_mycheckpointlapsdelta -= 256;
-                       if(race_mycheckpointenemy)
-                               strunzone(race_mycheckpointenemy);
                        int who = ReadByte();
                        if(who)
-                               race_mycheckpointenemy = strzone(entcs_GetName(who - 1));
+                               strcpy(race_mycheckpointenemy, entcs_GetName(who - 1));
                        else
-                               race_mycheckpointenemy = strzone(""); // TODO: maybe string_null works fine here?
+                               strcpy(race_mycheckpointenemy, ""); // TODO: maybe string_null works fine here?
                        break;
 
                case RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT:
@@ -1123,31 +1110,25 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_othercheckpointlapsdelta = ReadByte();
                        if(race_othercheckpointlapsdelta >= 128)
                                race_othercheckpointlapsdelta -= 256;
-                       if(race_othercheckpointenemy)
-                               strunzone(race_othercheckpointenemy);
                        int what = ReadByte();
                        if(what)
-                               race_othercheckpointenemy = strzone(entcs_GetName(what - 1));
+                               strcpy(race_othercheckpointenemy, entcs_GetName(what - 1));
                        else
-                               race_othercheckpointenemy = strzone(""); // TODO: maybe string_null works fine here?
+                               strcpy(race_othercheckpointenemy, ""); // TODO: maybe string_null works fine here?
                        break;
 
                case RACE_NET_PENALTY_RACE:
                        race_penaltyeventtime = time;
                        race_penaltytime = ReadShort();
                        //race_penaltyaccumulator += race_penaltytime;
-                       if(race_penaltyreason)
-                               strunzone(race_penaltyreason);
-                       race_penaltyreason = strzone(ReadString());
+                       strcpy(race_penaltyreason, ReadString());
                        break;
 
                case RACE_NET_PENALTY_QUALIFYING:
                        race_penaltyeventtime = time;
                        race_penaltytime = ReadShort();
                        race_penaltyaccumulator += race_penaltytime;
-                       if(race_penaltyreason)
-                               strunzone(race_penaltyreason);
-                       race_penaltyreason = strzone(ReadString());
+                       strcpy(race_penaltyreason, ReadString());
                        break;
 
                case RACE_NET_SERVER_RECORD:
@@ -1155,21 +1136,13 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        break;
                case RACE_NET_SPEED_AWARD:
                        race_speedaward = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
-                       if(race_speedaward_holder)
-                               strunzone(race_speedaward_holder);
-                       race_speedaward_holder = strzone(ReadString());
-                       if(race_speedaward_unit)
-                               strunzone(race_speedaward_unit);
-                       race_speedaward_unit = strzone(GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
+                       strcpy(race_speedaward_holder, ReadString());
+                       strcpy(race_speedaward_unit, GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
                        break;
                case RACE_NET_SPEED_AWARD_BEST:
                        race_speedaward_alltimebest = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
-                       if(race_speedaward_alltimebest_holder)
-                               strunzone(race_speedaward_alltimebest_holder);
-                       race_speedaward_alltimebest_holder = strzone(ReadString());
-                       if(race_speedaward_alltimebest_unit)
-                               strunzone(race_speedaward_alltimebest_unit);
-                       race_speedaward_alltimebest_unit = strzone(GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
+                       strcpy(race_speedaward_alltimebest_holder, ReadString());
+                       strcpy(race_speedaward_alltimebest_unit, GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
                        break;
                case RACE_NET_SERVER_RANKINGS:
                        float prevpos, del;
@@ -1182,47 +1155,35 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        if (prevpos) {
                                for (i=prevpos-1;i>pos-1;--i) {
                                        grecordtime[i] = grecordtime[i-1];
-                                       if(grecordholder[i])
-                                               strunzone(grecordholder[i]);
-                                       grecordholder[i] = strzone(grecordholder[i-1]);
+                                       strcpy(grecordholder[i], grecordholder[i-1]);
                                }
                        } else if (del) { // a record has been deleted by the admin
                                for (i=pos-1; i<= RANKINGS_CNT-1; ++i) {
                                        if (i == RANKINGS_CNT-1) { // clear out last record
                                                grecordtime[i] = 0;
-                                               if (grecordholder[i])
-                                                       strunzone(grecordholder[i]);
-                                               grecordholder[i] = string_null;
+                                               strfree(grecordholder[i]);
                                        }
                                        else {
                                                grecordtime[i] = grecordtime[i+1];
-                                               if (grecordholder[i])
-                                                       strunzone(grecordholder[i]);
-                                               grecordholder[i] = strzone(grecordholder[i+1]);
+                                               strcpy(grecordholder[i], grecordholder[i+1]);
                                        }
                                }
                        } else { // player has no ranked record yet
                                for (i=RANKINGS_CNT-1;i>pos-1;--i) {
                                        grecordtime[i] = grecordtime[i-1];
-                                       if(grecordholder[i])
-                                               strunzone(grecordholder[i]);
-                                       grecordholder[i] = strzone(grecordholder[i-1]);
+                                       strcpy(grecordholder[i], grecordholder[i-1]);
                                }
                        }
 
                        // store new ranking
-                       if(grecordholder[pos-1] != "")
-                               strunzone(grecordholder[pos-1]);
-                       grecordholder[pos-1] = strzone(ReadString());
+                       strcpy(grecordholder[pos-1], ReadString());
                        grecordtime[pos-1] = ReadInt24_t();
                        if(strdecolorize(grecordholder[pos-1]) == strdecolorize(entcs_GetName(player_localnum)))
                                race_myrank = pos;
                        break;
                case RACE_NET_SERVER_STATUS:
                        race_status = ReadShort();
-                       if(race_status_name)
-                               strunzone(race_status_name);
-                       race_status_name = strzone(ReadString());
+                       strcpy(race_status_name, ReadString());
        }
        return true;
 }
index fd1647ddcce350abe5a7af8ea85b2e2fe70f1630..01409280a4a4c9f535cf18e6c0f7f21b2eb1d8b0 100644 (file)
@@ -577,9 +577,7 @@ void Accuracy_LoadLevels()
 {
        if(autocvar_accuracy_color_levels != acc_color_levels)
        {
-               if(acc_color_levels)
-                       strunzone(acc_color_levels);
-               acc_color_levels = strzone(autocvar_accuracy_color_levels);
+               strcpy(acc_color_levels, autocvar_accuracy_color_levels);
                acc_levels = tokenize_console(acc_color_levels);
                if(acc_levels > MAX_ACCURACY_LEVELS)
                        acc_levels = MAX_ACCURACY_LEVELS;
index 5edb84ae0ee7fc42245871e32c1752d02939493b..cc6fced9b820a2885cf932118997f0bcfe44588b 100644 (file)
@@ -3,7 +3,7 @@
 #include <common/mutators/base.qh>
 
 // register all possible hooks here
+
 // to use a hook, first register your mutator using REGISTER_MUTATOR
 // then create your function using MUTATOR_HOOKFUNCTION
 
index 55e54d8ac2c641ad49b10bf03a979f0603eff9d3..220b9c6127ef958dd0b07c6312b44842240ac6e5 100644 (file)
@@ -8,13 +8,13 @@
 
 .float v_angle_save_x;
 
-class(Skeleton) .float skeleton_info_modelindex;
-class(Skeleton) .float skeleton_info_skin;
+classfield(Skeleton) .float skeleton_info_modelindex;
+classfield(Skeleton) .float skeleton_info_skin;
 const int BONETYPE_LOWER = 0;
 const int BONETYPE_UPPER = 1;
 const int MAX_BONES = 128;
-class(Skeleton) .float skeleton_bonetype[MAX_BONES];
-class(Skeleton) .float skeleton_numbones;
+classfield(Skeleton) .float skeleton_bonetype[MAX_BONES];
+classfield(Skeleton) .float skeleton_numbones;
 
 void skeleton_loadinfo(entity e)
 {
index 8c5969b09fb4db0ae068b7aa50338215be07b2dd..082335e4b0f61bedbdd39a62b6bc16f8376c9870 100644 (file)
@@ -7,8 +7,8 @@ void skeleton_from_frames(entity e, float is_dead);
 void skeleton_loadinfo(entity e);
 
 entityclass(Skeleton);
-class(Skeleton) .float bone_upperbody;
-class(Skeleton) .int bone_weapon;
-class(Skeleton) .float bone_aim[MAX_AIM_BONES];
-class(Skeleton) .float bone_aimweight[MAX_AIM_BONES];
-class(Skeleton) .float fixbone;
+classfield(Skeleton) .float bone_upperbody;
+classfield(Skeleton) .int bone_weapon;
+classfield(Skeleton) .float bone_aim[MAX_AIM_BONES];
+classfield(Skeleton) .float bone_aimweight[MAX_AIM_BONES];
+classfield(Skeleton) .float fixbone;
index 24f6568d26629396ff7322bfae3b97695f545d3d..a05ca701d03ab2abfc08495fffc6afb469d7f149 100644 (file)
@@ -1,10 +1,10 @@
 #pragma once
 
 entityclass(ShowNames);
-class(ShowNames) .float healthvalue;
-class(ShowNames) .float armorvalue;
-class(ShowNames) .float sameteam;
-class(ShowNames) .float fadedelay;
-class(ShowNames) .float pointtime;
+classfield(ShowNames) .float healthvalue;
+classfield(ShowNames) .float armorvalue;
+classfield(ShowNames) .float sameteam;
+classfield(ShowNames) .float fadedelay;
+classfield(ShowNames) .float pointtime;
 
 void Draw_ShowNames_All();
index 251c1a53f12a9185f0c5274839479066a4d7e759..41c7d46c564465924e272e585f249db640639b23 100644 (file)
@@ -4,10 +4,10 @@ const int MAX_TEAMRADAR_TIMES = 32;
 
 entityclass(TeamRadar);
 // to make entities have dots on the team radar
-class(TeamRadar) .float teamradar_icon;
-class(TeamRadar) .float teamradar_times[MAX_TEAMRADAR_TIMES];
-class(TeamRadar) .int teamradar_time_index;
-class(TeamRadar) .vector teamradar_color;
+classfield(TeamRadar) .float teamradar_icon;
+classfield(TeamRadar) .float teamradar_times[MAX_TEAMRADAR_TIMES];
+classfield(TeamRadar) .int teamradar_time_index;
+classfield(TeamRadar) .vector teamradar_color;
 
 float teamradar_angle; // player yaw angle
 vector teamradar_origin3d_in_texcoord; // player origin
index dd184bee9bbeb7d8dfcf3f5eb75abf7337d330b5..42a8820e761be63bcfed9abec1676438434f4a72 100644 (file)
@@ -1375,12 +1375,8 @@ void HUD_Crosshair(entity this)
                wcross_scale_goal_prev = 0;
                wcross_alpha_goal_prev = 0;
                wcross_changedonetime = 0;
-               if(wcross_name_goal_prev)
-                       strunzone(wcross_name_goal_prev);
-               wcross_name_goal_prev = string_null;
-               if(wcross_name_goal_prev_prev)
-                       strunzone(wcross_name_goal_prev_prev);
-               wcross_name_goal_prev_prev = string_null;
+               strfree(wcross_name_goal_prev);
+               strfree(wcross_name_goal_prev_prev);
                wcross_name_changestarttime = 0;
                wcross_name_changedonetime = 0;
                wcross_name_alpha_goal_prev = 0;
index b5728095485406213273f68f387c6096761de206..600bf5fa8fc9f13330d260895ca00d3066a0e026 100644 (file)
@@ -111,9 +111,7 @@ void Ent_Wall_Draw(entity this)
 
 void Ent_Wall_Remove(entity this)
 {
-       if(this.bgmscript)
-               strunzone(this.bgmscript);
-       this.bgmscript = string_null;
+       strfree(this.bgmscript);
 }
 
 NET_HANDLE(ENT_CLIENT_WALL, bool isnew)
@@ -186,17 +184,15 @@ NET_HANDLE(ENT_CLIENT_WALL, bool isnew)
                        this.mins = this.maxs = '0 0 0';
                setsize(this, this.mins, this.maxs);
 
-               if(this.bgmscript)
-                       strunzone(this.bgmscript);
-               this.bgmscript = ReadString();
-               if(substring(this.bgmscript, 0, 1) == "<")
+               string s = ReadString();
+               if(substring(s, 0, 1) == "<")
                {
-                       this.bgmscript = strzone(substring(this.bgmscript, 1, -1));
+                       strcpy(this.bgmscript, substring(s, 1, -1));
                        this.bgmscriptangular = 1;
                }
                else
                {
-                       this.bgmscript = strzone(this.bgmscript);
+                       strcpy(this.bgmscript, s);
                        this.bgmscriptangular = 0;
                }
                if(this.bgmscript != "")
index 11aebd0ed5e25df349f6fa12a8288e345e47f27f..e55bc489b3e7d6c1ac66c6936dc306ddd7d2e067 100644 (file)
@@ -1,11 +1,11 @@
 #pragma once
 
 entityclass(Wall);
-class(Wall) .float lip;
-class(Wall) .float bgmscriptangular;
-class(Wall) .int lodmodelindex0, lodmodelindex1, lodmodelindex2;
-class(Wall) .float loddistance1, loddistance2;
-class(Wall) .vector saved;
+classfield(Wall) .float lip;
+classfield(Wall) .float bgmscriptangular;
+classfield(Wall) .int lodmodelindex0, lodmodelindex1, lodmodelindex2;
+classfield(Wall) .float loddistance1, loddistance2;
+classfield(Wall) .vector saved;
 
 // Needed for interactive clientwalls
 .float inactive; // Clientwall disappears when inactive
index a6ae463477d51162d7364c55e35a4646d1ce20a5..eaa80d05f0a6ae2b9b6d5ebefb0c6041473b6488 100644 (file)
@@ -3,20 +3,20 @@
 #include <common/sounds/sound.qh>
 
 entityclass(Projectile);
-class(Projectile).int traileffect;
-
-class(Projectile).vector iorigin1, iorigin2;
-class(Projectile).float spawntime;
-class(Projectile).vector trail_oldorigin;
-class(Projectile).float trail_oldtime;
-class(Projectile).float fade_time, fade_rate;
-
-class(Projectile).float alphamod;
-class(Projectile).int count; // set if clientside projectile
-class(Projectile).int cnt;   // sound index
-class(Projectile).float gravity;
-class(Projectile).int snd_looping;
-class(Projectile).bool silent;
+classfield(Projectile).int traileffect;
+
+classfield(Projectile).vector iorigin1, iorigin2;
+classfield(Projectile).float spawntime;
+classfield(Projectile).vector trail_oldorigin;
+classfield(Projectile).float trail_oldtime;
+classfield(Projectile).float fade_time, fade_rate;
+
+classfield(Projectile).float alphamod;
+classfield(Projectile).int count; // set if clientside projectile
+classfield(Projectile).int cnt;   // sound index
+classfield(Projectile).float gravity;
+classfield(Projectile).int snd_looping;
+classfield(Projectile).bool silent;
 
 void SUB_Stop(entity this, entity toucher);
 
index d3efe77e844a498365a55ce6c264c5a554df0dd7..bc26203399bf44aace75bcff27b303f2caa738b0 100644 (file)
@@ -88,16 +88,15 @@ void CampaignFile_Unload()
 {
        if(campaign_title)
        {
-               strunzone(campaign_title);
+               strfree(campaign_title);
                for(int i = 0; i < campaign_entries; ++i)
                {
-                       strunzone(campaign_gametype[i]);
-                       strunzone(campaign_mapname[i]);
-                       strunzone(campaign_mutators[i]);
-                       strunzone(campaign_shortdesc[i]);
-                       strunzone(campaign_longdesc[i]);
+                       strfree(campaign_gametype[i]);
+                       strfree(campaign_mapname[i]);
+                       strfree(campaign_mutators[i]);
+                       strfree(campaign_shortdesc[i]);
+                       strfree(campaign_longdesc[i]);
                }
                campaign_entries = 0;
-               campaign_title = string_null;
        }
 }
index 936f1e028857e121d97fcdc985af76011bde90e3..983b073b406c8cfb93de92a31002d5dd1359fa56 100644 (file)
@@ -411,7 +411,7 @@ CLASS(DebugText3d, Object)
        }
 
        DESTRUCTOR(DebugText3d) {
-               strunzone(this.message);
+               strfree(this.message);
        }
 
        void DebugText3d_draw2d(DebugText3d this) {
index 71260eb3d04fa49ae2ffaeaca9c5b001ec8f8070..a1b27873053917e1ba6613d9939bc36d39f0395d 100644 (file)
@@ -327,7 +327,7 @@ REGISTRY(EffectInfos, BITS(9))
 #define EffectInfos_from(i) _EffectInfos_from(i, NULL)
 REGISTER_REGISTRY(EffectInfos)
 #define EFFECTINFO(name) \
-    [[accumulate]] void effectinfo_##name(EffectInfoGroup parent, EffectInfo this) { } \
+    ACCUMULATE void effectinfo_##name(EffectInfoGroup parent, EffectInfo this) { } \
     REGISTER(EffectInfos, EFFECTINFO, name, m_id, NEW(EffectInfoGroup)) { \
         effectinfo_##name(this, NULL); \
     }
@@ -335,8 +335,8 @@ REGISTER_REGISTRY(EffectInfos)
 #define MY(f) this.effectinfo_##f
 #define DEF(name) EFFECTINFO(name)
 #define SUB(name) \
-    [[accumulate]] void effectinfo_##name(EffectInfoGroup parent, EffectInfo this) { parent = EFFECTINFO_##name; parent.children[parent.children_count++] = this = NEW(EffectInfo, #name); } \
-    [[accumulate]] void effectinfo_##name(EffectInfoGroup parent, EffectInfo this)
+    ACCUMULATE void effectinfo_##name(EffectInfoGroup parent, EffectInfo this) { parent = EFFECTINFO_##name; parent.children[parent.children_count++] = this = NEW(EffectInfo, #name); } \
+    ACCUMULATE void effectinfo_##name(EffectInfoGroup parent, EffectInfo this)
 #include "effectinfo.inc"
 #undef MY
 #undef DEF
index 2abf2122c26553b86634a85eb7be3bd3ef1a5a3f..d225b337bc70bfd46d5dd55445d2ba6668b3bd7e 100644 (file)
@@ -30,10 +30,10 @@ void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float ran
 
 #ifdef CSQC
 entityclass(Casing);
-class(Casing) .float alpha;
-class(Casing) .bool silent;
-class(Casing) .int state;
-class(Casing) .float cnt;
+classfield(Casing) .float alpha;
+classfield(Casing) .bool silent;
+classfield(Casing) .int state;
+classfield(Casing) .float cnt;
 
 void Casing_Delete(entity this)
 {
index 4875a40ee98c4682b1d7cdf4f4c8818bce87ca39..8c0dfd5080312fda7d1ed4d10a66a108bdd34075 100644 (file)
                                .string fld = it.m_playersoundfld;
                                if (this.(fld))
                                {
-                                       strunzone(this.(fld));
-                                       this.(fld) = string_null;
+                                       strfree(this.(fld));
                                }
                        });
                }
                                }
                                string file = argv(1);
                                string variants = argv(2);
-                               if (this.(field)) strunzone(this.(field));
-                               this.(field) = strzone(strcat(file, " ", variants));
+                               strcpy(this.(field), strcat(file, " ", variants));
                        }
                        fclose(fh);
                        return true;
                void UpdatePlayerSounds(entity this)
                {
                        if (this.model == this.model_for_playersound && this.skin == this.skin_for_playersound) return;
-                       if (this.model_for_playersound) strunzone(this.model_for_playersound);
-                       this.model_for_playersound = strzone(this.model);
+                       strcpy(this.model_for_playersound, this.model);
                        this.skin_for_playersound = this.skin;
                        ClearPlayerSounds(this);
                        LoadPlayerSounds(this, "sound/player/default.sounds", true);
index 26b3ec9f5285744b9f21d72abd82cab86669c5c0..9849b5be73f8ebf3d1aef3ff5b1e61ec4dfea2d0 100644 (file)
@@ -80,10 +80,10 @@ void modeleffect_spawn(string m, float s, float f, vector o, vector v, vector an
 #ifdef CSQC
 
 entityclass(ModelEffect);
-class(ModelEffect) .float frame1time;
-class(ModelEffect) .float lifetime, fadetime;
-class(ModelEffect) .float teleport_time;
-class(ModelEffect) .float scale1, scale2;
+classfield(ModelEffect) .float frame1time;
+classfield(ModelEffect) .float lifetime, fadetime;
+classfield(ModelEffect) .float teleport_time;
+classfield(ModelEffect) .float scale1, scale2;
 
 .float cnt;
 .float scale;
index dd3785b68ea2cf65af3fb5ecc5c77f86c0b102e0..6eda9b15ef29d2b5c60a7b48e3651fcb5a538485 100644 (file)
@@ -3,7 +3,7 @@
 #ifdef CSQC
 
 entityclass(Rubble);
-class(Rubble).float creationtime;
+classfield(Rubble).float creationtime;
 
 IntrusiveList g_rubble;
 STATIC_INIT(g_rubble) { g_rubble = IL_NEW(); }
index 12abc21b18a255a29821912a00f8968ac1588ff9..0eeddc349bce72d747f55d2b1f3b8b3251ca7d50 100644 (file)
@@ -39,8 +39,7 @@ MACRO_END
 
 /** the engine player name strings are mutable! */
 #define ENTCS_SET_MUTABLE_STRING(var, x) MACRO_BEGIN \
-       if (var) strunzone(var); \
-       var = strzone(x); \
+       strcpy(var, x); \
 MACRO_END
 
 ENTCS_PROP(ENTNUM, false, sv_entnum, ENTCS_SET_NORMAL, {}, {}) /* sentinel */
@@ -63,11 +62,11 @@ ENTCS_PROP(ARMOR, false, armorvalue, ENTCS_SET_NORMAL,
 
 ENTCS_PROP(NAME, true, netname, ENTCS_SET_MUTABLE_STRING,
        { WriteString(chan, ent.netname); },
-       { if (ent.netname) strunzone(ent.netname); ent.netname = strzone(ReadString()); })
+       { strcpy(ent.netname, ReadString()); })
 
 ENTCS_PROP(MODEL, true, model, ENTCS_SET_NORMAL,
        { WriteString(chan, ent.model); },
-       { if (ent.model) strunzone(ent.model); ent.model = strzone(ReadString()); })
+       { strcpy(ent.model, ReadString()); })
 
 ENTCS_PROP(SKIN, true, skin, ENTCS_SET_NORMAL,
        { WriteByte(chan, ent.skin); },
@@ -168,10 +167,8 @@ ENTCS_PROP(FRAGS, true, frags, ENTCS_SET_NORMAL,
                int n = this.sv_entnum;
                entity e = entcs_receiver(n);
                entcs_receiver(n, NULL);
-               if (e.netname) strunzone(e.netname);
-               e.netname = string_null;
-               if (e.model) strunzone(e.model);
-               e.model = string_null;
+               strfree(e.netname);
+               strfree(e.model);
                if (e != this) delete(e);
        }
 
@@ -188,8 +185,7 @@ ENTCS_PROP(FRAGS, true, frags, ENTCS_SET_NORMAL,
                // `cl_forceplayermodels 1` sounds will be wrong until the player has been in the PVS, but so be it
                if (this.model != e.model)
                {
-                       if (this.model) strunzone(this.model);
-                       this.model = strzone(e.model);
+                       strcpy(this.model, e.model);
                }
        }
 
index 4790f1f1f785eaba2d48eb66a07fbb932a1d8f3f..b4195c05774eec2f08d780de5b4ddbff6cc687c5 100644 (file)
@@ -309,8 +309,7 @@ bool bd_move_dozer(entity minigame, entity dozer)
                                case BD_TILE_BRICK1: return false;
                        }
 
-                       if(hit.netname) { strunzone(hit.netname); }
-                       hit.netname = strzone(testpos);
+                       strcpy(hit.netname, testpos);
                        minigame_server_sendflags(hit,MINIG_SF_UPDATE);
                        break;
                }
@@ -330,8 +329,7 @@ bool bd_move_dozer(entity minigame, entity dozer)
                case BD_TILE_BRICK1: return false;
        }
 
-       if(dozer.netname) { strunzone(dozer.netname); }
-       dozer.netname = strzone(newpos);
+       strcpy(dozer.netname, newpos);
 
        return true;
 }
@@ -422,7 +420,7 @@ void bd_editor_place(entity minigame, entity player, string pos, int thetile, st
                                if(!piece)
                                        return; // how?!
 
-                               if(piece.netname) { strunzone(piece.netname); }
+                               strfree(piece.netname);
                                delete(piece);
                                minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
                                return;
@@ -488,12 +486,12 @@ void bd_unfill_recurse(entity minigame, entity player, int thetype, int letter,
 
        if(targ && thetype == targ.bd_tiletype)
        {
-               if(targ.netname) { strunzone(targ.netname); }
+               strfree(targ.netname);
                delete(targ);
        }
        else if(piece && thetype == piece.bd_tiletype)
        {
-               if(piece.netname) { strunzone(piece.netname); }
+               strfree(piece.netname);
                delete(piece);
        }
        else return;
@@ -568,7 +566,7 @@ void bd_setup_pieces(entity minigame)
        while( (e = findentity(e, owner, minigame)) )
                if(e.classname == "minigame_board_piece")
                {
-                       if(e.netname) { strunzone(e.netname); }
+                       strfree(e.netname);
                        delete(e);
                }
        e = NULL;
@@ -598,8 +596,7 @@ void bd_do_next_match(entity minigame, entity player)
 
        if(minigame.bd_nextlevel && minigame.bd_nextlevel != "")
        {
-               if(minigame.bd_levelname) { strunzone(minigame.bd_levelname); }
-               minigame.bd_levelname = strzone(minigame.bd_nextlevel);
+               strcpy(minigame.bd_levelname, minigame.bd_nextlevel);
        }
 
        bd_setup_pieces(minigame);
@@ -609,8 +606,7 @@ void bd_do_next_match(entity minigame, entity player)
 
 void bd_set_next_match(entity minigame, string next)
 {
-       if(minigame.bd_nextlevel) { strunzone(minigame.bd_nextlevel); }
-       minigame.bd_nextlevel = strzone(next);
+       strcpy(minigame.bd_nextlevel, next);
 }
 
 void bd_next_match(entity minigame, entity player, string next)
@@ -678,8 +674,7 @@ void bd_set_nextlevel(entity minigame, string s)
 {
        tokenize_console(s);
 
-       if(minigame.bd_nextlevel) { strunzone(minigame.bd_nextlevel); }
-       minigame.bd_nextlevel = strzone(argv(2));
+       strcpy(minigame.bd_nextlevel, argv(2));
 }
 
 int bd_fix_dir(vector dir)
@@ -854,8 +849,7 @@ int bd_server_event(entity minigame, string event, ...)
        {
                case "start":
                {
-                       if(minigame.bd_levelname) { strunzone(minigame.bd_levelname); }
-                       minigame.bd_levelname = strzone(autocvar_sv_minigames_bulldozer_startlevel);
+                       strcpy(minigame.bd_levelname, autocvar_sv_minigames_bulldozer_startlevel);
                        bd_setup_pieces(minigame);
                        minigame.minigame_flags = BD_TURN_MOVE;
 
@@ -867,7 +861,7 @@ int bd_server_event(entity minigame, string event, ...)
                        while( (e = findentity(e, owner, minigame)) )
                        if(e.classname == "minigame_board_piece")
                        {
-                               if(e.netname) { strunzone(e.netname); }
+                               strfree(e.netname);
                                delete(e);
                        }
                        e = NULL;
@@ -877,8 +871,8 @@ int bd_server_event(entity minigame, string event, ...)
                                delete(e);
                        }
 
-                       if(minigame.bd_nextlevel) { strunzone(minigame.bd_nextlevel); }
-                       if(minigame.bd_levelname) { strunzone(minigame.bd_levelname); }
+                       strfree(minigame.bd_nextlevel);
+                       strfree(minigame.bd_levelname);
                        return false;
                }
                case "join":
@@ -1209,8 +1203,7 @@ void bd_editor_fill(entity minigame)
 
 void bd_set_curr_pos(string s)
 {
-       if ( bd_curr_pos )
-               strunzone(bd_curr_pos);
+       strfree(bd_curr_pos);
        if ( s )
                s = strzone(s);
        bd_curr_pos = s;
@@ -1386,8 +1379,7 @@ int bd_client_event(entity minigame, string event, ...)
                                {
                                        int letter = ReadByte();
                                        int number = ReadByte();
-                                       if(sent.netname) { strunzone(sent.netname); }
-                                       sent.netname = strzone(minigame_tile_buildname(letter, number));
+                                       strcpy(sent.netname, minigame_tile_buildname(letter, number));
 
                                        sent.bd_tiletype = ReadByte();
 
index b3f5885c22380c9404284b610094090b1dad0ac1..c8f8184f5b0bd019862d1b73ecc631faea5084f1 100644 (file)
@@ -201,7 +201,7 @@ int c4_server_event(entity minigame, string event, ...)
                        while( (e = findentity(e, owner, minigame)) )
                        if(e.classname == "minigame_board_piece")
                        {
-                               if(e.netname) { strunzone(e.netname); }
+                               strfree(e.netname);
                                delete(e);
                        }
                        return false;
@@ -399,8 +399,7 @@ void c4_make_move(entity minigame)
 
 void c4_set_curr_pos(string s)
 {
-       if ( c4_curr_pos )
-               strunzone(c4_curr_pos);
+       strfree(c4_curr_pos);
        if ( s )
                s = strzone(s);
        c4_curr_pos = s;
index 82e09c324ab3982966ea7a08dc33f81527e50467..65ac9dee01db2940a47d53fc9e8ebf37eb55483c 100644 (file)
@@ -126,9 +126,9 @@ void nmm_kill_tiles(entity minig)
        while ( ( e = findentity(e,owner,minig) ) )
                if ( e.classname == "minigame_nmm_tile" )
                {
-                       strunzone(e.netname);
-                       strunzone(e.nmm_tile_hmill);
-                       strunzone(e.nmm_tile_vmill);
+                       strfree(e.netname);
+                       strfree(e.nmm_tile_hmill);
+                       strfree(e.nmm_tile_vmill);
                        delete(e);
                }
 }
index 40ddcca08b84c06e251a8165de2fe1e17c8051d7..0b1d74344e93f09fbe00877ecc2c8e6818c328ed 100644 (file)
@@ -121,7 +121,7 @@ void pp_move(entity minigame, entity player, string pos )
 
                        if(existing)
                        {
-                               if(existing.netname) { strunzone(existing.netname); }
+                               strfree(existing.netname);
                                delete(existing);
                        }
 
@@ -215,7 +215,7 @@ int pp_server_event(entity minigame, string event, ...)
                        while( (e = findentity(e, owner, minigame)) )
                        if(e.classname == "minigame_board_piece")
                        {
-                               if(e.netname) { strunzone(e.netname); }
+                               strfree(e.netname);
                                delete(e);
                        }
                        return false;
@@ -471,8 +471,7 @@ void pp_make_move(entity minigame)
 
 void pp_set_curr_pos(string s)
 {
-       if ( pp_curr_pos )
-               strunzone(pp_curr_pos);
+       strfree(pp_curr_pos);
        if ( s )
                s = strzone(s);
        pp_curr_pos = s;
index cd5c001e7adf95a30802b03bf468f857692bc9df..c8851f2ac4bad90e9f437751a20482182736050c 100644 (file)
@@ -139,11 +139,10 @@ bool ps_move_piece(entity minigame, entity piece, string pos, int leti, int numb
        if(!middle)
                return false;
 
-       if(middle.netname) { strunzone(middle.netname); }
+       strfree(middle.netname);
        delete(middle);
 
-       if(piece.netname) { strunzone(piece.netname); }
-       piece.netname = strzone(pos);
+       strcpy(piece.netname, pos);
 
        minigame_server_sendflags(piece,MINIG_SF_ALL);
 
@@ -232,7 +231,7 @@ int ps_server_event(entity minigame, string event, ...)
                        while( (e = findentity(e, owner, minigame)) )
                        if(e.classname == "minigame_board_piece")
                        {
-                               if(e.netname) { strunzone(e.netname); }
+                               strfree(e.netname);
                                delete(e);
                        }
                        return false;
@@ -514,8 +513,7 @@ void ps_make_move(entity minigame)
 
 void ps_set_curr_pos(string s)
 {
-       if ( ps_curr_pos )
-               strunzone(ps_curr_pos);
+       strfree(ps_curr_pos);
        if ( s )
                s = strzone(s);
        ps_curr_pos = s;
index c5a658054fe0d1e55192363b7e12cfd0abe9112b..a6cc50237736f010c2dab9500fa552426d974829 100644 (file)
@@ -147,7 +147,7 @@ int ttt_server_event(entity minigame, string event, ...)
                        while( (e = findentity(e, owner, minigame)) )
                        if(e.classname == "minigame_board_piece")
                        {
-                               if(e.netname) { strunzone(e.netname); }
+                               strfree(e.netname);
                                delete(e);
                        }
                        return false;
@@ -540,8 +540,7 @@ void ttt_make_move(entity minigame)
 
 void ttt_set_curr_pos(string s)
 {
-       if ( ttt_curr_pos )
-               strunzone(ttt_curr_pos);
+       strfree(ttt_curr_pos);
        if ( s )
                s = strzone(s);
        ttt_curr_pos = s;
index 415417b465f627ec1f3420e6c35e7291d08e401b..5c6af26615dc5f71363dfb9286eab23da294a859 100644 (file)
@@ -248,7 +248,7 @@ void end_minigame(entity minigame_session)
                delete(e);
        }
 
-       strunzone(minigame_session.netname);
+       strfree(minigame_session.netname);
        delete(minigame_session);
 }
 
index 7a1e7d73c2a471c802a1cf496d9a68e15c0d49e9..38aa4e33ada8d62930db4634610e5f2cb8610221 100644 (file)
@@ -1,10 +1,9 @@
 #pragma once
 
-#define setmodel(e, m) _setmodel((e), (m).model_str())
-
 CLASS(Model, Object)
     ATTRIB(Model, m_id, int, 0);
     ATTRIB(Model, model_str, string());
+    ATTRIB(Model, model_str_, string);
     CONSTRUCTOR(Model, string() path)
     {
         CONSTRUCT(Model);
@@ -20,5 +19,12 @@ CLASS(Model, Object)
         }
         profile(sprintf("precache_model(\"%s\")", s));
         precache_model(s);
+        strcpy(this.model_str_, s);
     }
 ENDCLASS(Model)
+
+#define setmodel(this, m) MACRO_BEGIN \
+    Model _setmodel_model = (m); \
+    string _setmodel_cached = _setmodel_model.model_str_; \
+    _setmodel((this), _setmodel_cached ? _setmodel_cached : _setmodel_model.model_str()); \
+MACRO_END
index bf019b9cf1771e1a2c1450b00c0a44b015b0c664..ccd10ee4532dcc911ad001862fa0866178f886fc 100644 (file)
@@ -276,7 +276,7 @@ void Monster_Sounds_Precache(entity this)
 
 void Monster_Sounds_Clear(entity this)
 {
-#define _MSOUND(m) if(this.monstersound_##m) { strunzone(this.monstersound_##m); this.monstersound_##m = string_null; }
+#define _MSOUND(m) strfree(this.monstersound_##m);
        ALLMONSTERSOUNDS
 #undef _MSOUND
 }
@@ -311,9 +311,7 @@ bool Monster_Sounds_Load(entity this, string f, int first)
                field = Monster_Sound_SampleField(argv(0));
                if(GetMonsterSoundSampleField_notFound)
                        continue;
-               if (this.(field))
-                       strunzone(this.(field));
-               this.(field) = strzone(strcat(argv(1), " ", argv(2)));
+               strcpy(this.(field), strcat(argv(1), " ", argv(2)));
        }
        fclose(fh);
        return true;
index d6989ad31839d52229cc8f612879fd6c83ab8686..d456282d429ee6fbc6c5113f90b7f57484b8fcff 100644 (file)
@@ -21,7 +21,7 @@ entity spawnmonster (entity e, string monster, int monster_id, entity spawnedby,
        if(monster == "random" || allow_any)
        {
                RandomSelection_Init();
-               FOREACH(Monsters, it != MON_Null && (allow_any || (!(it.spawnflags & MONSTER_TYPE_PASSIVE) && !(it.spawnflags & MON_FLAG_HIDDEN))),
+               FOREACH(Monsters, it != MON_Null && (allow_any || !(it.spawnflags & MON_FLAG_HIDDEN)) && !(it.spawnflags & MONSTER_TYPE_PASSIVE),
                {
                        RandomSelection_AddEnt(it, 1, 1);
                });
index 4f940c42b3c016f3e9131e0c6d3b213bc4d5497a..565e39998d7d4186d20ef3937f60ceddc9d53830 100644 (file)
@@ -135,7 +135,7 @@ void RegisterCallbacks() {};
         params(_MUTATOR_HANDLE_NOP,     _MUTATOR_HANDLE_POPOUT) \
         return ret; \
     } \
-    [[accumulate]] void RegisterHooks() { HOOK_##id = NEW(CallbackChain, #id); }
+    ACCUMULATE void RegisterHooks() { HOOK_##id = NEW(CallbackChain, #id); }
 
 #define MUTATOR_CALLHOOK(id, ...) _MUTATOR_CALLHOOK(id, __VA_ARGS__)
 #ifdef __STDC__
@@ -265,7 +265,7 @@ void Mutator_Remove(Mutator mut)
     bool MUTATOR_##id##_check() { return dependence; } \
     REGISTER(Mutators, MUTATOR, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \
     { this.mutatorcheck = MUTATOR_##id##_check; } \
-    [[accumulate]] bool MUTATORFUNCTION_##id(int mode)
+    ACCUMULATE bool MUTATORFUNCTION_##id(int mode)
 
 STATIC_INIT(Mutators) {
     RegisterHooks();
@@ -301,7 +301,7 @@ STATIC_INIT_LATE(Mutators) {
 #define _MUTATOR_CALLBACK(name, func) \
     Callback CALLBACK_##name; \
     bool func(); \
-    [[accumulate]] void RegisterCallbacks() { CALLBACK_##name = NEW(Callback, func); }
+    ACCUMULATE void RegisterCallbacks() { CALLBACK_##name = NEW(Callback, func); }
 
 #define MUTATOR_HOOKFUNCTION(...) \
     EVAL_MUTATOR_HOOKFUNCTION(OVERLOAD(MUTATOR_HOOKFUNCTION, __VA_ARGS__))
@@ -312,9 +312,9 @@ STATIC_INIT_LATE(Mutators) {
 
 #define MUTATOR_HOOKFUNCTION_3(mut, cb, order) \
     _MUTATOR_CALLBACK(mut##_##cb, mut##_##cb) \
-    [[accumulate]] bool MUTATORFUNCTION_##mut##_hooks(int mode) { MUTATOR_HOOK(cb, mut##_##cb, order); } \
+    ACCUMULATE bool MUTATORFUNCTION_##mut##_hooks(int mode) { MUTATOR_HOOK(cb, mut##_##cb, order); } \
     bool mut##_##cb() { return = false; } \
-    [[accumulate]] bool mut##_##cb()
+    ACCUMULATE bool mut##_##cb()
 
 #define MUTATOR_HOOK(cb, func, order) MACRO_BEGIN {                     \
     MUTATOR_ONADD {                                                     \
index 937f4cbde4ba00c19395d58c45dd7e6add6aba03..4a54d8117d24ba4ae80bf772e792d1ec1286464f 100644 (file)
@@ -926,7 +926,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
 
                BUFF_ONADD(BUFF_INVISIBLE)
                {
-                       if(time < player.strength_finished && g_instagib)
+                       if(time < player.strength_finished && autocvar_g_instagib)
                                player.buff_invisible_prev_alpha = default_player_alpha; // we don't want to save the powerup's alpha, as player may lose the powerup while holding the buff
                        else
                                player.buff_invisible_prev_alpha = player.alpha;
@@ -935,7 +935,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
 
                BUFF_ONREM(BUFF_INVISIBLE)
                {
-                       if(time < player.strength_finished && g_instagib)
+                       if(time < player.strength_finished && autocvar_g_instagib)
                                player.alpha = autocvar_g_instagib_invis_alpha;
                        else
                                player.alpha = player.buff_invisible_prev_alpha;
index a1fe27a877c3e46e5e4dfe59a15239c583930f0a..5f9de3b7cbfd906461a58d55d5edace06b9f71e6 100644 (file)
@@ -1,7 +1,7 @@
 #include "sv_cloaked.qh"
 
-string autocvar_g_cloaked;
-REGISTER_MUTATOR(cloaked, expr_evaluate(autocvar_g_cloaked));
+//string autocvar_g_cloaked;
+REGISTER_MUTATOR(cloaked, expr_evaluate(cvar_string("g_cloaked")));
 
 float autocvar_g_balance_cloaked_alpha;
 
index 0977b62cebe380b5172e0ef03c6d11f38546da54..5f8d8e68230623cb7fad6700b059895c72b5ff49 100644 (file)
@@ -155,8 +155,7 @@ CLASS(DamageText, Object)
             );
         }
 
-        if (this.text) strunzone(this.text);
-        this.text = strzone(s);
+        strcpy(this.text, s);
 
         this.m_size = map_bound_ranges(potential,
             autocvar_cl_damagetext_size_min_damage, autocvar_cl_damagetext_size_max_damage,
@@ -180,7 +179,7 @@ CLASS(DamageText, Object)
     }
 
     DESTRUCTOR(DamageText) {
-        if (this.text) strunzone(this.text);
+        strfree(this.text);
         if (this == DamageText_screen_first) {
             // start from 0 offset again, hopefully, others (if any) will have faded away by now
             DamageText_screen_first = NULL;
index 5603dd4901c0601cc8940320acbc1f87b6ab1f3e..2f8b45a99b46f09450ab44c93867b236b4ef4639 100644 (file)
@@ -1,7 +1,7 @@
 #include "sv_melee_only.qh"
 
 string autocvar_g_melee_only;
-REGISTER_MUTATOR(melee_only, expr_evaluate(autocvar_g_melee_only) && !cvar("g_instagib") && !cvar("g_overkill") && !g_nexball);
+REGISTER_MUTATOR(melee_only, expr_evaluate(autocvar_g_melee_only) && !autocvar_g_instagib && !cvar("g_overkill") && !g_nexball);
 
 MUTATOR_HOOKFUNCTION(melee_only, SetStartItems, CBC_ORDER_LAST)
 {
index ec2593215a09b5187abd522608e07dc6f978e141..3ac652d7807df5d1ee4797dad9f16134b25dd756 100644 (file)
@@ -70,11 +70,11 @@ roflsound "New toys, new toys!" sound.
 
 */
 
-string autocvar_g_new_toys;
+//string autocvar_g_new_toys;
 
 bool nt_IsNewToy(int w);
 
-REGISTER_MUTATOR(nt, expr_evaluate(autocvar_g_new_toys) && !cvar("g_instagib") && !cvar("g_overkill"))
+REGISTER_MUTATOR(nt, expr_evaluate(cvar_string("g_new_toys")) && !autocvar_g_instagib && !cvar("g_overkill"))
 {
        MUTATOR_ONADD
        {
index 953321cc0ba5a708bb30d73e0e218b8e4ad67cf0..e88ff9b552984feb7a083932173d64939709ab52 100644 (file)
@@ -1,6 +1,6 @@
 #include "sv_nix.qh"
 
-string autocvar_g_nix;
+//string autocvar_g_nix;
 int autocvar_g_balance_nix_ammo_cells;
 int autocvar_g_balance_nix_ammo_plasma;
 int autocvar_g_balance_nix_ammo_fuel;
@@ -36,7 +36,7 @@ float nix_nextweapon;
 
 bool NIX_CanChooseWeapon(int wpn);
 
-REGISTER_MUTATOR(nix, expr_evaluate(autocvar_g_nix) && !cvar("g_instagib") && !cvar("g_overkill"))
+REGISTER_MUTATOR(nix, expr_evaluate(cvar_string("g_nix")) && !autocvar_g_instagib && !cvar("g_overkill"))
 {
        MUTATOR_ONADD
        {
index e9106239467ffc7432cda21fa887481db192a6cc..582a8d35bcb9cfcd42182f8064312ef4fd3dc449 100644 (file)
@@ -11,7 +11,7 @@ bool autocvar_g_overkill_itemwaypoints = true;
 
 .Weapon ok_lastwep[MAX_WEAPONSLOTS];
 
-REGISTER_MUTATOR(ok, expr_evaluate(autocvar_g_overkill) && !cvar("g_instagib") && !g_nexball && cvar_string("g_mod_balance") == "Overkill")
+REGISTER_MUTATOR(ok, expr_evaluate(autocvar_g_overkill) && !autocvar_g_instagib && !g_nexball && cvar_string("g_mod_balance") == "Overkill")
 {
        MUTATOR_ONADD
        {
index 1084ff77895aa079e2dd9104ffe1159551f54db2..c5bf2262eb35e37523c3ac83caa559d4ef1e8d6d 100644 (file)
@@ -1,7 +1,7 @@
 #include "sv_pinata.qh"
 
 string autocvar_g_pinata;
-REGISTER_MUTATOR(pinata, expr_evaluate(autocvar_g_pinata) && !cvar("g_instagib") && !cvar("g_overkill"));
+REGISTER_MUTATOR(pinata, expr_evaluate(autocvar_g_pinata) && !autocvar_g_instagib && !cvar("g_overkill"));
 
 MUTATOR_HOOKFUNCTION(pinata, PlayerDies)
 {
index 7edef9813de0fd3c13ca1d79d6593674202c32c1..c6def68e1b61f6ddb56f76bdac458ad3ef5db931 100644 (file)
@@ -3,7 +3,7 @@
 #include <common/deathtypes/all.qh>
 #include <server/round_handler.qh>
 
-REGISTER_MUTATOR(rm, cvar("g_instagib"));
+REGISTER_MUTATOR(rm, autocvar_g_instagib);
 
 MUTATOR_HOOKFUNCTION(rm, Damage_Calculate)
 {
index d121cf1094685ac9263f55143b59da831cf37610..d80b21d5a6e0cec3b4a59f5c403b948eece5cd85 100644 (file)
@@ -212,11 +212,11 @@ void sandbox_ObjectRemove(entity e)
        // if the object being removed has been selected for attachment by a player, unset it
        FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.object_attach == e, { it.object_attach = NULL; });
 
-       if(e.material)  {       strunzone(e.material);  e.material = string_null;       }
-       if(e.crypto_idfp)       {       strunzone(e.crypto_idfp);       e.crypto_idfp = string_null;    }
-       if(e.netname)   {       strunzone(e.netname);   e.netname = string_null;        }
-       if(e.message)   {       strunzone(e.message);   e.message = string_null;        }
-       if(e.message2)  {       strunzone(e.message2);  e.message2 = string_null;       }
+       strfree(e.material);
+       strfree(e.crypto_idfp);
+       strfree(e.netname);
+       strfree(e.message);
+       strfree(e.message2);
        delete(e);
        e = NULL;
 
@@ -357,14 +357,14 @@ entity sandbox_ObjectPort_Load(entity this, string s, float database)
                e.old_movetype = stof(argv(argv_num));  ++argv_num;
                set_movetype(e, e.old_movetype);
                e.damageforcescale = stof(argv(argv_num));      ++argv_num;
-               if(e.material)  strunzone(e.material);  if(argv(argv_num) != "")        e.material = strzone(argv(argv_num));   else    e.material = string_null;       ++argv_num;
+               strfree(e.material);    if(argv(argv_num) != "")        e.material = strzone(argv(argv_num));   else    e.material = string_null;       ++argv_num;
                if(database)
                {
                        // properties stored only for the database
-                       if(e.crypto_idfp)       strunzone(e.crypto_idfp);       if(argv(argv_num) != "")        e.crypto_idfp = strzone(argv(argv_num));        else    e.crypto_idfp = string_null;    ++argv_num;
-                       if(e.netname)   strunzone(e.netname);   e.netname = strzone(argv(argv_num));    ++argv_num;
-                       if(e.message)   strunzone(e.message);   e.message = strzone(argv(argv_num));    ++argv_num;
-                       if(e.message2)  strunzone(e.message2);  e.message2 = strzone(argv(argv_num));   ++argv_num;
+                       strfree(e.crypto_idfp); if(argv(argv_num) != "")        e.crypto_idfp = strzone(argv(argv_num));        else    e.crypto_idfp = string_null;    ++argv_num;
+                       strcpy(e.netname, argv(argv_num));      ++argv_num;
+                       strcpy(e.message, argv(argv_num));      ++argv_num;
+                       strcpy(e.message2, argv(argv_num));     ++argv_num;
                }
 
                // attach last
@@ -702,7 +702,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                                        e.damageforcescale = stof(argv(3));
                                                        break;
                                                case "material":
-                                                       if(e.material)  strunzone(e.material);
+                                                       strfree(e.material);
                                                        if(argv(3))
                                                        {
                                                                for (j = 1; j <= 5; j++) // precache material sounds, 5 in total
@@ -718,8 +718,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                        }
 
                                        // update last editing time
-                                       if(e.message2)  strunzone(e.message2);
-                                       e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S"));
+                                       strcpy(e.message2, strftime(true, "%d-%m-%Y %H:%M:%S"));
 
                                        if(autocvar_g_sandbox_info > 1)
                                                LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin));
@@ -745,8 +744,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                        // also update the player's nickname if he changed it (but has the same player UID)
                                        if(e.netname != player.netname)
                                        {
-                                               if(e.netname)   strunzone(e.netname);
-                                               e.netname = strzone(player.netname);
+                                               strcpy(e.netname, player.netname);
                                                print_to(player, "^2SANDBOX - INFO: ^7Object owner name updated");
                                        }
 
@@ -756,8 +754,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                                return true;
                                        }
 
-                                       if(e.crypto_idfp)       strunzone(e.crypto_idfp);
-                                       e.crypto_idfp = strzone(player.crypto_idfp);
+                                       strcpy(e.crypto_idfp, player.crypto_idfp);
 
                                        print_to(player, "^2SANDBOX - INFO: ^7Object claimed successfully");
                                }
index 199b4e202a7351a9b2d25bfb4364ec02119a259d..b599805a45774f6d971087191a259ebffef342c1 100644 (file)
@@ -1,7 +1,7 @@
 #include "sv_vampire.qh"
 
 string autocvar_g_vampire;
-REGISTER_MUTATOR(vampire, expr_evaluate(autocvar_g_vampire) && !cvar("g_instagib"));
+REGISTER_MUTATOR(vampire, expr_evaluate(autocvar_g_vampire) && !autocvar_g_instagib);
 
 MUTATOR_HOOKFUNCTION(vampire, PlayerDamage_SplitHealthArmor)
 {
index be5b40c14c40c99301f8e91a7d54e08a017f9f65..0faf7068cf396d2320c56353c49bf2025ce54882 100644 (file)
@@ -106,9 +106,9 @@ NET_HANDLE(waypointsprites, bool isnew) {
 
 void Ent_RemoveWaypointSprite(entity this)
 {
-    if (this.netname) strunzone(this.netname);
-    if (this.netname2) strunzone(this.netname2);
-    if (this.netname3) strunzone(this.netname3);
+    strfree(this.netname);
+    strfree(this.netname2);
+    strfree(this.netname3);
 }
 
 /** flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable] */
@@ -169,23 +169,17 @@ void Ent_WaypointSprite(entity this, bool isnew)
 
     if (sendflags & 2)
     {
-        if (this.netname)
-            strunzone(this.netname);
-        this.netname = strzone(ReadString());
+        strcpy(this.netname, ReadString());
     }
 
     if (sendflags & 4)
     {
-        if (this.netname2)
-            strunzone(this.netname2);
-        this.netname2 = strzone(ReadString());
+        strcpy(this.netname2, ReadString());
     }
 
     if (sendflags & 8)
     {
-        if (this.netname3)
-            strunzone(this.netname3);
-        this.netname3 = strzone(ReadString());
+        strcpy(this.netname3, ReadString());
     }
 
     if (sendflags & 16)
index 95b8890ccce07b10765c5dae8218d9d265b223bc..94d735a1f6096b2f3a77a0b712e4124912bb0aa3 100644 (file)
@@ -11,21 +11,21 @@ const int SPRITERULE_SPECTATOR = 2;
 
 #ifdef CSQC
 entityclass(WaypointSprite);
-class(WaypointSprite) .float helpme;
-class(WaypointSprite) .float rule;
-class(WaypointSprite) .string netname; // primary picture
-class(WaypointSprite) .string netname2; // secondary picture
-class(WaypointSprite) .string netname3; // tertiary picture
-class(WaypointSprite) .int team; // team that gets netname2
-class(WaypointSprite) .float lifetime;
-class(WaypointSprite) .float fadetime;
-class(WaypointSprite) .float maxdistance;
-class(WaypointSprite) .int hideflags;
-class(WaypointSprite) .float spawntime;
-class(WaypointSprite) .float health;
-class(WaypointSprite) .float build_started;
-class(WaypointSprite) .float build_starthealth;
-class(WaypointSprite) .float build_finished;
+classfield(WaypointSprite) .float helpme;
+classfield(WaypointSprite) .float rule;
+classfield(WaypointSprite) .string netname; // primary picture
+classfield(WaypointSprite) .string netname2; // secondary picture
+classfield(WaypointSprite) .string netname3; // tertiary picture
+classfield(WaypointSprite) .int team; // team that gets netname2
+classfield(WaypointSprite) .float lifetime;
+classfield(WaypointSprite) .float fadetime;
+classfield(WaypointSprite) .float maxdistance;
+classfield(WaypointSprite) .int hideflags;
+classfield(WaypointSprite) .float spawntime;
+classfield(WaypointSprite) .float health;
+classfield(WaypointSprite) .float build_started;
+classfield(WaypointSprite) .float build_starthealth;
+classfield(WaypointSprite) .float build_finished;
 
 float autocvar_g_waypointsprite_alpha;
 float autocvar_g_waypointsprite_crosshairfadealpha;
index b9350758a115fb6ab3558c86e867a5e62d549c73..644d049d38e8d92c6f86ad49c8e3487fd5092380 100644 (file)
@@ -1063,8 +1063,7 @@ void Local_Notification_sound(int soundchannel, string soundfile, float soundvol
 
                _sound(NULL, soundchannel, AnnouncerFilename(soundfile), soundvolume, soundposition);
 
-               if (prev_soundfile) strunzone(prev_soundfile);
-               prev_soundfile = strzone(soundfile);
+               strcpy(prev_soundfile, soundfile);
                prev_soundtime = time;
        }
        else
@@ -1467,7 +1466,7 @@ void Net_Notification_Remove(entity this)
                this.owner.nent_name
        ));
        #endif
-       for (int i = 0; i < this.nent_stringcount; ++i) { if (this.nent_strings[i]) strunzone(this.nent_strings[i]); }
+       for (int i = 0; i < this.nent_stringcount; ++i) { strfree(this.nent_strings[i]); }
        delete(this);
 }
 
index 351725bc14698fe92da40c5aa533947e5a7e0381..1b80655026dcf4b2fdc00a7cf79b4bd5e628d7ed 100644 (file)
@@ -98,42 +98,51 @@ float GeomLerp(float a, float _lerp, float b)
 
 void PM_ClientMovement_UpdateStatus(entity this)
 {
-#ifdef CSQC
        if(!IS_PLAYER(this))
                return;
 
-       // set crouched
-       bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
+       bool have_hook = false;
        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
-               entity wep = viewmodels[slot];
-               if(wep.hook && !wasfreed(wep.hook))
+       #if defined(CSQC)
+               entity wepent = viewmodels[slot];
+       #elif defined(SVQC)
+               .entity weaponentity = weaponentities[slot];
+               entity wepent = this.(weaponentity);
+       #endif
+               if(wepent.hook && !wasfreed(wepent.hook))
                {
-                       do_crouch = false;
-                       break; // don't bother checking the others
+                       have_hook = true;
+                       break;
                }
        }
-       //if(this.waterlevel >= WATERLEVEL_SWIMMING)
+       bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
+       if (have_hook) {
+               do_crouch = false;
+       //} else if (this.waterlevel >= WATERLEVEL_SWIMMING) {
                //do_crouch = false;
-       if(hud != HUD_NORMAL)
+       } else if (PHYS_INVEHICLE(this)) {
                do_crouch = false;
-       if(STAT(FROZEN, this))
+       } else if (STAT(FROZEN, this)) {
                do_crouch = false;
+    }
 
-       if (do_crouch)
-       {
-               // wants to crouch, this always works
-               if (!IS_DUCKED(this)) SET_DUCKED(this);
-       }
-       else
-       {
-               // wants to stand, if currently crouching we need to check for a low ceiling first
-               if (IS_DUCKED(this))
-               {
-                       tracebox(this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), this.origin, MOVE_NORMAL, this);
-                       if (!trace_startsolid) UNSET_DUCKED(this);
+       if (do_crouch) {
+               if (!IS_DUCKED(this)) {
+                       SET_DUCKED(this);
+                       this.view_ofs = STAT(PL_CROUCH_VIEW_OFS, this);
+                       setsize(this, STAT(PL_CROUCH_MIN, this), STAT(PL_CROUCH_MAX, this));
+                       // setanim(this, this.anim_duck, false, true, true); // this anim is BROKEN anyway
                }
+       } else if (IS_DUCKED(this)) {
+        tracebox(this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), this.origin, false, this);
+        if (!trace_startsolid) {
+            UNSET_DUCKED(this);
+            this.view_ofs = STAT(PL_VIEW_OFS, this);
+            setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
+        }
        }
+#ifdef CSQC
 
        if (IS_ONGROUND(this) || this.velocity.z <= 0 || PHYS_WATERJUMP_TIME(this) <= 0)
                PHYS_WATERJUMP_TIME(this) = 0;
index 02a0126ad81c29a4dd9efcca7f6405db7bb8931a..da48fa698c2086e34049c7fc1ffeb0f9599d5a87 100644 (file)
@@ -231,6 +231,8 @@ STATIC_INIT(PHYS_INPUT_BUTTON)
        #define SET_DUCKED(s)                       ((s).flags |= FL_DUCKED)
        #define UNSET_DUCKED(s)                     ((s).flags &= ~FL_DUCKED)
 
+       #define PHYS_INVEHICLE(s)                                       (boolean(hud != HUD_NORMAL))
+
        #define PHYS_JUMPSPEEDCAP_MIN               autocvar_cl_jumpspeedcap_min
        #define PHYS_JUMPSPEEDCAP_MAX               autocvar_cl_jumpspeedcap_max
 
@@ -283,6 +285,8 @@ STATIC_INIT(PHYS_INPUT_BUTTON)
        #define SET_DUCKED(s)                       ((s).crouch = true)
        #define UNSET_DUCKED(s)                     ((s).crouch = false)
 
+       #define PHYS_INVEHICLE(s)                                       (boolean((s).vehicle != NULL))
+
        #define PHYS_JUMPSPEEDCAP_MIN               autocvar_sv_jumpspeedcap_min
        #define PHYS_JUMPSPEEDCAP_MAX               autocvar_sv_jumpspeedcap_max
 
index 0fcd70dfc08fd8e7afd9bdc2cd2b31c063331c79..cde6a519028093268ef95fc568e91184a40d3368 100644 (file)
@@ -154,8 +154,7 @@ void PlayerStats_GameReport_FinalizePlayer(entity p)
                }
        }
 
-       strunzone(p.playerstats_id);
-       p.playerstats_id = string_null;
+       strfree(p.playerstats_id);
 }
 
 void PlayerStats_GameReport(float finished)
index 8c4aecbda029829c753e9b1641ceeb490cc04259..d46ac9eafc7c36cccbeb07c7d302fe9b25f250d3 100644 (file)
@@ -22,7 +22,7 @@ const int CH_PLAYER_SINGLE = 7;
 // const int CH_BGM_SINGLE = -8;
 const int CH_BGM_SINGLE = 8;
 const int CH_AMBIENT = -9;
-// const int CH_AMBIENT_SINGLE = 9;
+const int CH_AMBIENT_SINGLE = 9;
 
 const float ATTEN_NONE = 0;
 const float ATTEN_MIN = 0.015625;
@@ -92,40 +92,55 @@ const float VOL_MUFFLED = 0.35;
                } \
        } MACRO_END
 
+string _Sound_fixpath(string base)
+{
+       if (base == "") return string_null;
+#ifdef SVQC
+       return strcat(base, ".wav");  // let the client engine decide
+#else
+#define extensions(x) \
+       x(wav) \
+       x(ogg) \
+       x(flac) \
+       /**/
+#define tryext(ext) { \
+               string s = strcat(base, "." #ext); \
+               if (fexists(strcat("sound/", s))) { \
+                       return s; \
+               } \
+       }
+       extensions(tryext);
+       LOG_WARNF("Missing sound: \"%s\"", strcat("sound/", base));
+#undef tryext
+#undef extensions
+       return string_null;
+#endif
+}
+
 CLASS(Sound, Object)
        ATTRIB(Sound, m_id, int, 0);
        ATTRIB(Sound, sound_str, string());
+       ATTRIB(Sound, sound_str_, string);
        CONSTRUCTOR(Sound, string() path)
        {
                CONSTRUCT(Sound);
                this.sound_str = path;
        }
-       #define Sound_fixpath(this) _Sound_fixpath((this).sound_str())
-       string _Sound_fixpath(string base)
-       {
-               if (base == "") return string_null;
-#ifdef SVQC
-               return strcat(base, ".wav");  // let the client engine decide
-#else
-               #define extensions(x) \
-                       x(wav) \
-                       x(ogg) \
-                       x(flac) \
-                       /**/
-               #define tryext(ext) { string s = strcat(base, "." #ext); if (fexists(strcat("sound/", s))) return s; }
-               extensions(tryext);
-               LOG_WARNF("Missing sound: \"%s\"", strcat("sound/", base));
-               #undef tryext
-               #undef extensions
-               return string_null;
-#endif
-       }
        METHOD(Sound, sound_precache, void(Sound this))
        {
            TC(Sound, this);
-               string s = Sound_fixpath(this);
+               string s = _Sound_fixpath(this.sound_str());
                if (!s) return;
                profile(sprintf("precache_sound(\"%s\")", s));
                precache_sound(s);
+               strcpy(this.sound_str_, s);
        }
 ENDCLASS(Sound)
+
+entity _Sound_fixpath_this;
+string _Sound_fixpath_cached;
+#define Sound_fixpath(this) ( \
+       _Sound_fixpath_this = (this), \
+       _Sound_fixpath_cached = _Sound_fixpath_this.sound_str_, \
+       _Sound_fixpath_cached ? _Sound_fixpath_cached : _Sound_fixpath(_Sound_fixpath_this.sound_str()) \
+)
index 02a0dc171cc34723e95e7671fde5504b80da47e0..039d27da351f284a3766d9684a6bbf2c45838b72 100644 (file)
@@ -148,8 +148,17 @@ void Item_PreDraw(entity this)
 
 void ItemRemove(entity this)
 {
-       if(this.mdl)
-               strunzone(this.mdl);
+       strfree(this.mdl);
+}
+
+HashMap ENT_CLIENT_ITEM_simple;
+STATIC_INIT(ENT_CLIENT_ITEM_simple)
+{
+       HM_NEW(ENT_CLIENT_ITEM_simple);
+}
+SHUTDOWN(ENT_CLIENT_ITEM_simple)
+{
+       HM_DELETE(ENT_CLIENT_ITEM_simple);
 }
 
 NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
@@ -211,10 +220,8 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
         if(!warpzone_warpzones_exist && this.fade_start && !autocvar_cl_items_nofade)
                setpredraw(this, Item_PreDraw);
 
-        if(this.mdl)
-            strunzone(this.mdl);
+               strfree(this.mdl);
 
-        this.mdl = "";
         string _fn = ReadString();
         this.item_simple = false; // reset it!
 
@@ -223,27 +230,37 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
             string _fn2 = substring(_fn, 0 , strlen(_fn) -4);
             this.item_simple = true;
 
-            if(fexists(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".md3")))
-                this.mdl = strzone(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".md3"));
-            else if(fexists(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".dpm")))
-                this.mdl = strzone(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".dpm"));
-            else if(fexists(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".iqm")))
-                this.mdl = strzone(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".iqm"));
-            else if(fexists(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".mdl")))
-                this.mdl = strzone(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".mdl"));
-            else
-            {
-                this.item_simple = false;
-                LOG_TRACE("Simple item requested for ", _fn, " but no model exists for it");
-            }
+                       #define extensions(x) \
+                               x(md3) \
+                               x(dpm) \
+                               x(iqm) \
+                               x(mdl) \
+                               /**/
+                       #define tryext(ext) { \
+                               string s = strcat(_fn2, autocvar_cl_simpleitems_postfix, "." #ext); \
+                               string cached = HM_gets(ENT_CLIENT_ITEM_simple, s); \
+                               if (cached == "") { \
+                                       HM_sets(ENT_CLIENT_ITEM_simple, s, cached = fexists(s) ? "1" : "0"); \
+                               } \
+                               if (cached != "0") { \
+                                       strcpy(this.mdl, s); \
+                                       break; \
+                               } \
+                       }
+                       do {
+                               extensions(tryext);
+                               this.item_simple = false;
+                LOG_TRACEF("Simple item requested for %s but no model exists for it", _fn);
+                       } while (0);
+                       #undef tryext
+                       #undef extensions
         }
 
         if(!this.item_simple)
-            this.mdl = strzone(_fn);
-
+            strcpy(this.mdl, _fn);
 
         if(this.mdl == "")
-            LOG_TRACE("^1WARNING!^7 this.mdl is unset for item ", this.classname, ", tell tZork about this!");
+            LOG_WARNF("this.mdl is unset for item %s", this.classname);
 
         precache_model(this.mdl);
         _setmodel(this, this.mdl);
diff --git a/qcsrc/common/triggers/defs.qh b/qcsrc/common/triggers/defs.qh
new file mode 100644 (file)
index 0000000..45afb51
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma once
+
+//-----------
+// SPAWNFLAGS
+//-----------
+const int START_ENABLED = BIT(0);
+const int START_DISABLED = BIT(0);
+const int ALL_ENTITIES = BIT(1);
+const int ON_MAPLOAD = BIT(1);
+const int INVERT_TEAMS = BIT(2);
+const int CRUSH = BIT(2);
+const int NOSPLASH = BIT(8); // generic anti-splashdamage spawnflag
+const int ONLY_PLAYERS = BIT(14);
+
+// triggers
+const int SPAWNFLAG_NOMESSAGE = BIT(0);
+const int SPAWNFLAG_NOTOUCH = BIT(0);
+
+//----------
+// SENDFLAGS
+//----------
+const int SF_TRIGGER_INIT = BIT(0);
+const int SF_TRIGGER_UPDATE = BIT(1);
+const int SF_TRIGGER_RESET = BIT(2);
+
+//----------------
+// STATES & ACTIVE
+//----------------
+#ifdef CSQC
+// this stuff is defined in the server side engine VM, so we must define it separately here
+const int STATE_TOP = 0;
+const int STATE_BOTTOM = 1;
+const int STATE_UP = 2;
+const int STATE_DOWN = 3;
+
+const int ACTIVE_NOT = 0;
+const int ACTIVE_ACTIVE = 1;
+const int ACTIVE_IDLE = 2;
+const int ACTIVE_BUSY = 2;
+const int ACTIVE_TOGGLE = 3;
+#endif
index ff8841a570030853d2ce70b1602bc06ba2c31c60..b647e15a826e48164f03db46c5f62114a8e6afc6 100644 (file)
@@ -59,9 +59,9 @@ spawnfunc(func_bobbing)
        this.dmgtime2 = time;
 
        // how far to bob
-       if (this.spawnflags & 1) // X
+       if (this.spawnflags & BOBBING_XAXIS)
                this.movedir = '1 0 0' * this.height;
-       else if (this.spawnflags & 2) // Y
+       else if (this.spawnflags & BOBBING_YAXIS)
                this.movedir = '0 1 0' * this.height;
        else // Z
                this.movedir = '0 0 1' * this.height;
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..58f7bb71456e37eaa43a744d8aeb28a06a877269 100644 (file)
@@ -1 +1,5 @@
 #pragma once
+
+
+const int BOBBING_XAXIS = BIT(0);
+const int BOBBING_YAXIS = BIT(1);
index ec71bc3fc3b044e10888e56a1e8a6d0d4c872c32..d09ccd5e00a8cede8584138723c607d37637ea9c 100644 (file)
 //   target = targets to trigger when broken
 //   health = amount of damage it can take
 //   spawnflags:
-//     1 = start disabled (needs to be triggered to activate)
-//     2 = indicate damage
-//     4 = don't take direct damage (needs to be triggered to 'explode', then triggered again to restore)
+//     START_DISABLED: needs to be triggered to activate
+//     BREAKABLE_INDICATE_DAMAGE: indicate damage
+//     BREAKABLE_NODAMAGE: don't take direct damage (needs to be triggered to 'explode', then triggered again to restore)
+//     NOSPLASH: don't take splash damage
 // notes:
 //   for mdl_dead to work, origin must be set (using a common/origin brush).
 //   Otherwise mdl_dead will be displayed at the map origin, and nobody would
@@ -81,7 +82,7 @@ void LaunchDebris (entity this, string debrisname, vector force)
 void func_breakable_colormod(entity this)
 {
        float h;
-       if (!(this.spawnflags & 2))
+       if (!(this.spawnflags & BREAKABLE_INDICATE_DAMAGE))
                return;
        h = this.health / this.max_health;
        if(h < 0.25)
@@ -135,8 +136,8 @@ void func_breakable_behave_destroyed(entity this)
                IL_REMOVE(g_bot_targets, this);
        this.bot_attack = false;
        this.event_damage = func_null;
-       this.state = 1;
-       if(this.spawnflags & 4)
+       this.state = STATE_BROKEN;
+       if(this.spawnflags & BREAKABLE_NODAMAGE)
                this.use = func_null;
        func_breakable_colormod(this);
        if (this.noise1)
@@ -158,7 +159,7 @@ void func_breakable_behave_restore(entity this)
                WaypointSprite_UpdateMaxHealth(this.sprite, this.max_health);
                WaypointSprite_UpdateHealth(this.sprite, this.health);
        }
-       if(!(this.spawnflags & 4))
+       if(!(this.spawnflags & BREAKABLE_NODAMAGE))
        {
                this.takedamage = DAMAGE_AIM;
                if(!this.bot_attack)
@@ -166,9 +167,9 @@ void func_breakable_behave_restore(entity this)
                this.bot_attack = true;
                this.event_damage = func_breakable_damage;
        }
-       if(this.spawnflags & 4)
+       if(this.spawnflags & BREAKABLE_NODAMAGE)
                this.use = func_breakable_destroy; // don't need to set it usually, as .use isn't reset
-       this.state = 0;
+       this.state = STATE_ALIVE;
        //this.nextthink = 0; // cancel auto respawn
        setthink(this, func_breakable_think);
        this.nextthink = time + 0.1;
@@ -179,7 +180,7 @@ void func_breakable_behave_restore(entity this)
 
 void func_breakable_init_for_player(entity this, entity player)
 {
-       if (this.noise1 && this.state == 0 && IS_REAL_CLIENT(player))
+       if (this.noise1 && this.state == STATE_ALIVE && IS_REAL_CLIENT(player))
        {
                msg_entity = player;
                soundto (MSG_ONE, this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
@@ -248,9 +249,9 @@ void func_breakable_destroy_self(entity this)
 
 void func_breakable_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
-       if(this.state == 1)
+       if(this.state == STATE_BROKEN)
                return;
-       if(this.spawnflags & DOOR_NOSPLASH)
+       if(this.spawnflags & NOSPLASH)
                if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
                        return;
        if(this.team)
@@ -290,7 +291,7 @@ void func_breakable_reset(entity this)
 {
        this.team = this.team_saved;
        func_breakable_look_restore(this);
-       if(this.spawnflags & 1)
+       if(this.spawnflags & START_DISABLED)
                func_breakable_behave_destroyed(this);
        else
                func_breakable_behave_restore(this);
@@ -330,12 +331,12 @@ spawnfunc(func_breakable)
        this.mdl = this.model;
        SetBrushEntityModel(this);
 
-       if(this.spawnflags & 4)
+       if(this.spawnflags & BREAKABLE_NODAMAGE)
                this.use = func_breakable_destroy;
        else
                this.use = func_breakable_restore;
 
-       if(this.spawnflags & 4)
+       if(this.spawnflags & BREAKABLE_NODAMAGE)
        {
                this.takedamage = DAMAGE_NO;
                this.event_damage = func_null;
index 761a2c7a98f350fe53629bc13f74e3874eb19673..0efbcfaed5eb809c544d2f245d02467096b56ba7 100644 (file)
@@ -1,5 +1,12 @@
 #pragma once
 
+
+const int BREAKABLE_INDICATE_DAMAGE = BIT(1);
+const int BREAKABLE_NODAMAGE = BIT(2);
+
+const int STATE_ALIVE = 0;
+const int STATE_BROKEN = 1;
+
 #ifdef SVQC
 spawnfunc(func_breakable);
 #endif
index c51c034f1681caef48773e01172325e19b7848e9..28e6481c880886c18d240fc3cc55719eb80668d6 100644 (file)
@@ -91,7 +91,7 @@ void button_touch(entity this, entity toucher)
 
 void button_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
-       if(this.spawnflags & DOOR_NOSPLASH)
+       if(this.spawnflags & NOSPLASH)
                if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
                        return;
        if (this.spawnflags & BUTTON_DONTACCUMULATEDMG)
@@ -123,11 +123,7 @@ When a button is touched, it moves some distance in the direction of it's angle,
 "wait"         override the default 1 second wait (-1 = never return)
 "lip"          override the default 4 pixel lip remaining at end of move
 "health"       if set, the button must be killed instead of touched. If set to -1, the button will fire on ANY attack, even damageless ones like the InstaGib laser
-"sounds"
-0) steam metal
-1) wooden clunk
-2) metallic click
-3) in-out
+"noise"                sound that is played when the button is activated
 */
 spawnfunc(func_button)
 {
index 75a6006eb5e703e24b79362c9df7b0f39e328376..86a0fc918050846f848a47a981295a292223cf3b 100644 (file)
@@ -1,3 +1,4 @@
 #pragma once
 
-const int BUTTON_DONTACCUMULATEDMG = 128;
+
+const int BUTTON_DONTACCUMULATEDMG = BIT(7);
index 1802a75db4a96a74ab2b56eb9531a748923bfa91..9ad326cfa225f7ef9b0c08151e96f4feeacdff39 100644 (file)
@@ -17,9 +17,9 @@ void conveyor_think(entity this)
                IL_REMOVE(g_conveyed, it);
        });
 
-       if(this.state)
+       if(this.active == ACTIVE_ACTIVE)
        {
-               FOREACH_ENTITY_RADIUS((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1, !it.conveyor.state && isPushable(it),
+               FOREACH_ENTITY_RADIUS((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1, it.conveyor.active == ACTIVE_NOT && isPushable(it),
                {
                        vector emin = it.absmin;
                        vector emax = it.absmax;
@@ -63,26 +63,12 @@ void conveyor_think(entity this)
 
 #ifdef SVQC
 
-void conveyor_use(entity this, entity actor, entity trigger)
-{
-       this.state = !this.state;
-
-       this.SendFlags |= 2;
-}
-
-void conveyor_reset(entity this)
-{
-       this.state = (this.spawnflags & 1);
-
-       this.SendFlags |= 2;
-}
-
-bool conveyor_send(entity this, entity to, int sf)
+bool conveyor_send(entity this, entity to, int sendflags)
 {
        WriteHeader(MSG_ENTITY, ENT_CLIENT_CONVEYOR);
-       WriteByte(MSG_ENTITY, sf);
+       WriteByte(MSG_ENTITY, sendflags);
 
-       if(sf & 1)
+       if(sendflags & SF_TRIGGER_INIT)
        {
                WriteByte(MSG_ENTITY, this.warpzone_isboxy);
                WriteVector(MSG_ENTITY, this.origin);
@@ -93,14 +79,14 @@ bool conveyor_send(entity this, entity to, int sf)
                WriteVector(MSG_ENTITY, this.movedir);
 
                WriteByte(MSG_ENTITY, this.speed);
-               WriteByte(MSG_ENTITY, this.state);
+               WriteByte(MSG_ENTITY, this.active);
 
                WriteString(MSG_ENTITY, this.targetname);
                WriteString(MSG_ENTITY, this.target);
        }
 
-       if(sf & 2)
-               WriteByte(MSG_ENTITY, this.state);
+       if(sendflags & SF_TRIGGER_UPDATE)
+               WriteByte(MSG_ENTITY, this.active);
 
        return true;
 }
@@ -111,20 +97,20 @@ void conveyor_init(entity this)
        this.movedir *= this.speed;
        setthink(this, conveyor_think);
        this.nextthink = time;
+       this.setactive = generic_netlinked_setactive;
        IFTARGETED
        {
-               this.use = conveyor_use;
-               this.reset = conveyor_reset;
-               this.reset(this);
+               // backwards compatibility
+               this.use = generic_netlinked_legacy_use;
        }
-       else
-               this.state = 1;
+       this.reset = generic_netlinked_reset;
+       this.reset(this);
 
        FixSize(this);
 
        Net_LinkEntity(this, 0, false, conveyor_send);
 
-       this.SendFlags |= 1;
+       this.SendFlags |= SF_TRIGGER_INIT;
 }
 
 spawnfunc(trigger_conveyor)
@@ -161,9 +147,9 @@ void conveyor_init(entity this, bool isnew)
 
 NET_HANDLE(ENT_CLIENT_CONVEYOR, bool isnew)
 {
-       int sf = ReadByte();
+       int sendflags = ReadByte();
 
-       if(sf & 1)
+       if(sendflags & SF_TRIGGER_INIT)
        {
                this.warpzone_isboxy = ReadByte();
                this.origin = ReadVector();
@@ -176,7 +162,7 @@ NET_HANDLE(ENT_CLIENT_CONVEYOR, bool isnew)
                this.movedir = ReadVector();
 
                this.speed = ReadByte();
-               this.state = ReadByte();
+               this.active = ReadByte();
 
                this.targetname = strzone(ReadString());
                this.target = strzone(ReadString());
@@ -184,8 +170,8 @@ NET_HANDLE(ENT_CLIENT_CONVEYOR, bool isnew)
                conveyor_init(this, isnew);
        }
 
-       if(sf & 2)
-               this.state = ReadByte();
+       if(sendflags & SF_TRIGGER_UPDATE)
+               this.active = ReadByte();
 
        return true;
 }
index c12b52d2dd19118e4d0a7209329796446922cbeb..22b674ff36098192b0c8409a029122e6b88ec4b1 100644 (file)
@@ -1,4 +1,5 @@
 #pragma once
+#include "../defs.qh"
 
 IntrusiveList g_conveyed;
 STATIC_INIT(g_conveyed) { g_conveyed = IL_NEW(); }
index f768717c6bbde4c18c6ba50c6b05a7e773466b3a..c19041aa0b1b7ad2269597caa1ea93040a26afa6 100644 (file)
@@ -1,4 +1,5 @@
 #include "door.qh"
+#include "door_rotating.qh"
 /*
 
 Doors are similar to buttons, but can spawn a fat trigger field around them
@@ -23,12 +24,10 @@ THINK FUNCTIONS
 
 void door_go_down(entity this);
 void door_go_up(entity this, entity actor, entity trigger);
-void door_rotating_go_down(entity this);
-void door_rotating_go_up(entity this, entity oth);
 
 void door_blocked(entity this, entity blocker)
 {
-       if((this.spawnflags & 8)
+       if((this.spawnflags & DOOR_CRUSH)
 #ifdef SVQC
                && (blocker.takedamage != DAMAGE_NO)
 #elif defined(CSQC)
@@ -57,21 +56,19 @@ void door_blocked(entity this, entity blocker)
                        if (this.wait >= 0)
                        {
                                if (this.state == STATE_DOWN)
-                       if (this.classname == "door")
-                       {
-                               door_go_up (this, NULL, NULL);
-                       } else
-                       {
-                               door_rotating_go_up(this, blocker);
-                       }
+                               {
+                                       if (this.classname == "door")
+                                               door_go_up(this, NULL, NULL);
+                                       else
+                                               door_rotating_go_up(this, blocker);
+                               }
                                else
-                       if (this.classname == "door")
-                       {
-                               door_go_down (this);
-                       } else
-                       {
-                               door_rotating_go_down (this);
-                       }
+                               {
+                                       if (this.classname == "door")
+                                               door_go_down(this);
+                                       else
+                                               door_rotating_go_down(this);
+                               }
                        }
                }
 #ifdef SVQC
@@ -179,7 +176,7 @@ bool door_check_keys(entity door, entity player)
        if(!door.itemkeys)
        {
 #ifdef SVQC
-               play2(player, SND(TALK));
+               play2(player, door.noise);
                Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_DOOR_UNLOCKED);
 #endif
                return true;
@@ -240,12 +237,12 @@ void door_fire(entity this, entity actor, entity trigger)
                        door_go_up(e, actor, trigger);
                } else {
                        // if the BIDIR spawnflag (==2) is set and the trigger has set trigger_reverse, reverse the opening direction
-                       if ((e.spawnflags & 2) && trigger.trigger_reverse!=0 && e.lip != 666 && e.state == STATE_BOTTOM) {
+                       if ((e.spawnflags & DOOR_ROTATING_BIDIR) && trigger.trigger_reverse!=0 && e.lip != 666 && e.state == STATE_BOTTOM) {
                                e.lip = 666; // e.lip is used to remember reverse opening direction for door_rotating
                                e.pos2 = '0 0 0' - e.pos2;
                        }
                        // if BIDIR_IN_DOWN (==8) is set, prevent the door from reoping during closing if it is triggered from the wrong side
-                       if (!((e.spawnflags & 2) &&  (e.spawnflags & 8) && e.state == STATE_DOWN
+                       if (!((e.spawnflags & DOOR_ROTATING_BIDIR) &&  (e.spawnflags & DOOR_ROTATING_BIDIR_IN_DOWN) && e.state == STATE_DOWN
                                && (((e.lip == 666) && (trigger.trigger_reverse == 0)) || ((e.lip != 666) && (trigger.trigger_reverse != 0)))))
                        {
                                door_rotating_go_up(e, trigger);
@@ -265,7 +262,7 @@ void door_use(entity this, entity actor, entity trigger)
 
 void door_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
-       if(this.spawnflags & DOOR_NOSPLASH)
+       if(this.spawnflags & NOSPLASH)
                if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
                        return;
        this.health = this.health - damage;
@@ -315,7 +312,7 @@ void door_touch(entity this, entity toucher)
 
 void door_generic_plat_blocked(entity this, entity blocker)
 {
-       if((this.spawnflags & 8) && (blocker.takedamage != DAMAGE_NO)) { // Kill Kill Kill!!
+       if((this.spawnflags & DOOR_CRUSH) && (blocker.takedamage != DAMAGE_NO)) { // Kill Kill Kill!!
 #ifdef SVQC
                Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
 #endif
@@ -350,66 +347,6 @@ void door_generic_plat_blocked(entity this, entity blocker)
        }
 }
 
-void door_rotating_hit_top(entity this)
-{
-       if (this.noise1 != "")
-               _sound (this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
-       this.state = STATE_TOP;
-       if (this.spawnflags & DOOR_TOGGLE)
-               return;         // don't come down automatically
-       setthink(this, door_rotating_go_down);
-       this.nextthink = this.ltime + this.wait;
-}
-
-void door_rotating_hit_bottom(entity this)
-{
-       if (this.noise1 != "")
-               _sound (this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
-       if (this.lip==666) // this.lip is used to remember reverse opening direction for door_rotating
-       {
-               this.pos2 = '0 0 0' - this.pos2;
-               this.lip = 0;
-       }
-       this.state = STATE_BOTTOM;
-}
-
-void door_rotating_go_down(entity this)
-{
-       if (this.noise2 != "")
-               _sound (this, CH_TRIGGER_SINGLE, this.noise2, VOL_BASE, ATTEN_NORM);
-       if (this.max_health)
-       {
-               this.takedamage = DAMAGE_YES;
-               this.health = this.max_health;
-       }
-
-       this.state = STATE_DOWN;
-       SUB_CalcAngleMove (this, this.pos1, TSPEED_LINEAR, this.speed, door_rotating_hit_bottom);
-}
-
-void door_rotating_go_up(entity this, entity oth)
-{
-       if (this.state == STATE_UP)
-               return;         // already going up
-
-       if (this.state == STATE_TOP)
-       {       // reset top wait time
-               this.nextthink = this.ltime + this.wait;
-               return;
-       }
-       if (this.noise2 != "")
-               _sound (this, CH_TRIGGER_SINGLE, this.noise2, VOL_BASE, ATTEN_NORM);
-       this.state = STATE_UP;
-       SUB_CalcAngleMove (this, this.pos2, TSPEED_LINEAR, this.speed, door_rotating_hit_top);
-
-       string oldmessage;
-       oldmessage = this.message;
-       this.message = "";
-       SUB_UseTargets(this, NULL, oth); // TODO: is oth needed here?
-       this.message = oldmessage;
-}
-
-
 /*
 =========================================
 door trigger
@@ -467,7 +404,7 @@ LinkDoors
 
 entity LinkDoors_nextent(entity cur, entity near, entity pass)
 {
-       while((cur = find(cur, classname, pass.classname)) && ((cur.spawnflags & 4) || cur.enemy))
+       while((cur = find(cur, classname, pass.classname)) && ((cur.spawnflags & DOOR_DONT_LINK) || cur.enemy))
        {
        }
        return cur;
@@ -500,7 +437,7 @@ void LinkDoors(entity this)
 
        if (this.enemy)
                return;         // already linked by another door
-       if (this.spawnflags & 4)
+       if (this.spawnflags & DOOR_DONT_LINK)
        {
                this.owner = this.enemy = this;
 
@@ -690,53 +627,93 @@ void door_reset(entity this)
 
 #ifdef SVQC
 
-// spawnflags require key (for now only func_door)
-spawnfunc(func_door)
+// common code for func_door and func_door_rotating spawnfuncs
+void door_init_shared(entity this)
 {
-       // Quake 1 keys compatibility
-       if (this.spawnflags & SPAWNFLAGS_GOLD_KEY)
-               this.itemkeys |= ITEM_KEY_BIT(0);
-       if (this.spawnflags & SPAWNFLAGS_SILVER_KEY)
-               this.itemkeys |= ITEM_KEY_BIT(1);
-
-       SetMovedir(this);
-
        this.max_health = this.health;
-       if (!InitMovingBrushTrigger(this))
-               return;
-       this.effects |= EF_LOWPRECISION;
-       this.classname = "door";
 
+       // unlock sound
        if(this.noise == "")
+       {
                this.noise = "misc/talk.wav";
+       }
+       // door still locked sound
        if(this.noise3 == "")
+       {
                this.noise3 = "misc/talk.wav";
+       }
        precache_sound(this.noise);
        precache_sound(this.noise3);
 
-       setblocked(this, door_blocked);
-       this.use = door_use;
-
-       if(this.dmg && (this.message == ""))
+       if((this.dmg || (this.spawnflags & DOOR_CRUSH)) && (this.message == ""))
+       {
                this.message = "was squished";
-       if(this.dmg && (this.message2 == ""))
+       }
+       if((this.dmg || (this.spawnflags & DOOR_CRUSH)) && (this.message2 == ""))
+       {
                this.message2 = "was squished by";
+       }
 
+       // TODO: other soundpacks
        if (this.sounds > 0)
        {
                this.noise2 = "plats/medplat1.wav";
                this.noise1 = "plats/medplat2.wav";
        }
 
-       if(this.noise1 && this.noise1 != "") { precache_sound(this.noise1); }
-       if(this.noise2 && this.noise2 != "") { precache_sound(this.noise2); }
+       // sound when door stops moving
+       if(this.noise1 && this.noise1 != "")
+       {
+               precache_sound(this.noise1);
+       }
+       // sound when door is moving
+       if(this.noise2 && this.noise2 != "")
+       {
+               precache_sound(this.noise2);
+       }
 
-       if (!this.speed)
-               this.speed = 100;
        if (!this.wait)
+       {
                this.wait = 3;
+       }
        if (!this.lip)
+       {
                this.lip = 8;
+       }
+
+       this.state = STATE_BOTTOM;
+
+       if (this.health)
+       {
+               //this.canteamdamage = true; // TODO
+               this.takedamage = DAMAGE_YES;
+               this.event_damage = door_damage;
+       }
+
+       if (this.items)
+       {
+               this.wait = -1;
+       }
+}
+
+// spawnflags require key (for now only func_door)
+spawnfunc(func_door)
+{
+       // Quake 1 keys compatibility
+       if (this.spawnflags & SPAWNFLAGS_GOLD_KEY)
+               this.itemkeys |= ITEM_KEY_BIT(0);
+       if (this.spawnflags & SPAWNFLAGS_SILVER_KEY)
+               this.itemkeys |= ITEM_KEY_BIT(1);
+
+       SetMovedir(this);
+
+       if (!InitMovingBrushTrigger(this))
+               return;
+       this.effects |= EF_LOWPRECISION;
+       this.classname = "door";
+
+       setblocked(this, door_blocked);
+       this.use = door_use;
 
        this.pos1 = this.origin;
        this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);
@@ -749,18 +726,13 @@ spawnfunc(func_door)
        if (this.spawnflags & DOOR_START_OPEN)
                InitializeEntity(this, door_init_startopen, INITPRIO_SETLOCATION);
 
-       this.state = STATE_BOTTOM;
+       door_init_shared(this);
 
-       if (this.health)
+       if (!this.speed)
        {
-               //this.canteamdamage = true; // TODO
-               this.takedamage = DAMAGE_YES;
-               this.event_damage = door_damage;
+               this.speed = 100;
        }
 
-       if (this.items)
-               this.wait = -1;
-
        settouch(this, door_touch);
 
 // LinkDoors can't be done until all of the doors have been spawned, so
index 84a9d6aa234224fe3d2d35b6c1640941c73b85f1..181de8b7b829592dc0ce3dcaf426524a824d78d2 100644 (file)
@@ -1,16 +1,15 @@
 #pragma once
 
-// door constants
-const int DOOR_START_OPEN = 1;
-const int DOOR_DONT_LINK = 4;
-const int DOOR_TOGGLE = 32;
 
-const int DOOR_NOSPLASH = 256; // generic anti-splashdamage spawnflag
+const int DOOR_START_OPEN = BIT(0);
+const int DOOR_DONT_LINK = BIT(2);
+const int SPAWNFLAGS_GOLD_KEY = BIT(3); // Quake 1 compat, can only be used with func_door!
+const int SPAWNFLAGS_SILVER_KEY = BIT(4); // Quake 1 compat, can only be used with func_door!
+const int DOOR_TOGGLE = BIT(5);
 
-const int DOOR_NONSOLID = 1024;
+const int DOOR_NONSOLID = BIT(10);
+const int DOOR_CRUSH = BIT(11); // can't use CRUSH cause that is the same as DOOR_DONT_LINK
 
-const int SPAWNFLAGS_GOLD_KEY = 8;
-const int SPAWNFLAGS_SILVER_KEY = 16;
 
 #ifdef CSQC
 // stuff for preload
index c61a02686650eb56ae3a138d3cace85fed2a99b0..41fd05e574af53295a71c6b105c3a76f3ac78e52 100644 (file)
@@ -1,5 +1,4 @@
 #include "door_rotating.qh"
-#ifdef SVQC
 /*QUAKED spawnfunc_func_door_rotating (0 .5 .8) ? START_OPEN BIDIR DOOR_DONT_LINK BIDIR_IN_DOWN x TOGGLE X_AXIS Y_AXIS
 if two doors touch, they are assumed to be connected and operate as a unit.
 
@@ -28,6 +27,68 @@ START_OPEN causes the door to move to its destination when spawned, and operate
 FIXME: only one sound set available at the time being
 */
 
+#ifdef GAMEQC
+void door_rotating_hit_top(entity this)
+{
+       if (this.noise1 != "")
+               _sound (this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
+       this.state = STATE_TOP;
+       if (this.spawnflags & DOOR_TOGGLE)
+               return;         // don't come down automatically
+       setthink(this, door_rotating_go_down);
+       this.nextthink = this.ltime + this.wait;
+}
+
+void door_rotating_hit_bottom(entity this)
+{
+       if (this.noise1 != "")
+               _sound (this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
+       if (this.lip==666) // this.lip is used to remember reverse opening direction for door_rotating
+       {
+               this.pos2 = '0 0 0' - this.pos2;
+               this.lip = 0;
+       }
+       this.state = STATE_BOTTOM;
+}
+
+void door_rotating_go_down(entity this)
+{
+       if (this.noise2 != "")
+               _sound (this, CH_TRIGGER_SINGLE, this.noise2, VOL_BASE, ATTEN_NORM);
+       if (this.max_health)
+       {
+               this.takedamage = DAMAGE_YES;
+               this.health = this.max_health;
+       }
+
+       this.state = STATE_DOWN;
+       SUB_CalcAngleMove (this, this.pos1, TSPEED_LINEAR, this.speed, door_rotating_hit_bottom);
+}
+
+void door_rotating_go_up(entity this, entity oth)
+{
+       if (this.state == STATE_UP)
+               return;         // already going up
+
+       if (this.state == STATE_TOP)
+       {       // reset top wait time
+               this.nextthink = this.ltime + this.wait;
+               return;
+       }
+       if (this.noise2 != "")
+               _sound (this, CH_TRIGGER_SINGLE, this.noise2, VOL_BASE, ATTEN_NORM);
+       this.state = STATE_UP;
+       SUB_CalcAngleMove (this, this.pos2, TSPEED_LINEAR, this.speed, door_rotating_hit_top);
+
+       string oldmessage;
+       oldmessage = this.message;
+       this.message = "";
+       SUB_UseTargets(this, NULL, oth); // TODO: is oth needed here?
+       this.message = oldmessage;
+}
+#endif
+
+#ifdef SVQC
 void door_rotating_reset(entity this)
 {
        this.angles = this.pos1;
@@ -44,17 +105,15 @@ void door_rotating_init_startopen(entity this)
        this.pos1 = this.movedir;
 }
 
-
 spawnfunc(func_door_rotating)
 {
-
        //if (!this.deathtype) // map makers can override this
        //      this.deathtype = " got in the way";
 
        // I abuse "movedir" for denoting the axis for now
-       if (this.spawnflags & 64) // X (untested)
+       if (this.spawnflags & DOOR_ROTATING_XAXIS)
                this.movedir = '0 0 1';
-       else if (this.spawnflags & 128) // Y (untested)
+       else if (this.spawnflags & DOOR_ROTATING_YAXIS)
                this.movedir = '1 0 0';
        else // Z
                this.movedir = '0 1 0';
@@ -64,7 +123,6 @@ spawnfunc(func_door_rotating)
        this.movedir = this.movedir * this.angles_y;
        this.angles = '0 0 0';
 
-       this.max_health = this.health;
        this.avelocity = this.movedir;
        if (!InitMovingBrushTrigger(this))
                return;
@@ -75,28 +133,6 @@ spawnfunc(func_door_rotating)
        setblocked(this, door_blocked);
        this.use = door_use;
 
-    if(this.spawnflags & 8)
-        this.dmg = 10000;
-
-    if(this.dmg && (this.message == ""))
-               this.message = "was squished";
-    if(this.dmg && (this.message2 == ""))
-               this.message2 = "was squished by";
-
-    if (this.sounds > 0)
-       {
-               precache_sound ("plats/medplat1.wav");
-               precache_sound ("plats/medplat2.wav");
-               this.noise2 = "plats/medplat1.wav";
-               this.noise1 = "plats/medplat2.wav";
-       }
-
-       if (!this.speed)
-               this.speed = 50;
-       if (!this.wait)
-               this.wait = 1;
-       this.lip = 0; // this.lip is used to remember reverse opening direction for door_rotating
-
        this.pos1 = '0 0 0';
        this.pos2 = this.movedir;
 
@@ -105,17 +141,12 @@ spawnfunc(func_door_rotating)
        if (this.spawnflags & DOOR_START_OPEN)
                InitializeEntity(this, door_rotating_init_startopen, INITPRIO_SETLOCATION);
 
-       this.state = STATE_BOTTOM;
-
-       if (this.health)
+       door_init_shared(this);
+       if (!this.speed)
        {
-               //this.canteamdamage = true; // TODO
-               this.takedamage = DAMAGE_YES;
-               this.event_damage = door_damage;
+               this.speed = 50;
        }
-
-       if (this.items)
-               this.wait = -1;
+       this.lip = 0; // this.lip is used to remember reverse opening direction for door_rotating
 
        settouch(this, door_touch);
 
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..5ff572859b5c1847c32c504cb3b95fac53f7cf40 100644 (file)
@@ -1 +1,14 @@
 #pragma once
+
+
+const int DOOR_ROTATING_BIDIR = BIT(1);
+const int DOOR_ROTATING_BIDIR_IN_DOWN = BIT(3);
+
+const int DOOR_ROTATING_XAXIS = BIT(6);
+const int DOOR_ROTATING_YAXIS = BIT(7);
+
+
+#ifdef GAMEQC
+void door_rotating_go_down(entity this);
+void door_rotating_go_up(entity this, entity oth);
+#endif
index 55582696476e8b543ea80cb6b94a59bdaebae27b..78e0dd64e9cafc275eb55c1a6d1302cdcde2cdd5 100644 (file)
@@ -8,12 +8,6 @@ void fd_secret_move5(entity this);
 void fd_secret_move6(entity this);
 void fd_secret_done(entity this);
 
-const float SECRET_OPEN_ONCE = 1;              // stays open
-const float SECRET_1ST_LEFT = 2;               // 1st move is left of arrow
-const float SECRET_1ST_DOWN = 4;               // 1st move is down from arrow
-const float SECRET_NO_SHOOT = 8;               // only opened by trigger
-const float SECRET_YES_SHOOT = 16;     // shootable even if targeted
-
 void fd_secret_use(entity this, entity actor, entity trigger)
 {
        float temp;
@@ -41,12 +35,12 @@ void fd_secret_use(entity this, entity actor, entity trigger)
                _sound(this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
        this.nextthink = this.ltime + 0.1;
 
-       temp = 1 - (this.spawnflags & SECRET_1ST_LEFT); // 1 or -1
+       temp = 1 - (this.spawnflags & DOOR_SECRET_1ST_LEFT);    // 1 or -1
        makevectors(this.mangle);
 
        if (!this.t_width)
        {
-               if (this.spawnflags & SECRET_1ST_DOWN)
+               if (this.spawnflags & DOOR_SECRET_1ST_DOWN)
                        this.t_width = fabs(v_up * this.size);
                else
                        this.t_width = fabs(v_right * this.size);
@@ -55,7 +49,7 @@ void fd_secret_use(entity this, entity actor, entity trigger)
        if (!this.t_length)
                this.t_length = fabs(v_forward * this.size);
 
-       if (this.spawnflags & SECRET_1ST_DOWN)
+       if (this.spawnflags & DOOR_SECRET_1ST_DOWN)
                this.dest1 = this.origin - v_up * this.t_width;
        else
                this.dest1 = this.origin + v_right * (this.t_width * temp);
@@ -93,7 +87,7 @@ void fd_secret_move3(entity this)
 {
        if (this.noise3 != "")
                _sound(this, CH_TRIGGER_SINGLE, this.noise3, VOL_BASE, ATTEN_NORM);
-       if (!(this.spawnflags & SECRET_OPEN_ONCE))
+       if (!(this.spawnflags & DOOR_SECRET_OPEN_ONCE) && this.wait >= 0)
        {
                this.nextthink = this.ltime + this.wait;
                setthink(this, fd_secret_move4);
@@ -126,7 +120,7 @@ void fd_secret_move6(entity this)
 
 void fd_secret_done(entity this)
 {
-       if (this.spawnflags&SECRET_YES_SHOOT)
+       if (this.spawnflags&DOOR_SECRET_YES_SHOOT)
        {
                this.health = 10000;
                this.takedamage = DAMAGE_YES;
@@ -172,7 +166,7 @@ void secret_touch(entity this, entity toucher)
 
 void secret_reset(entity this)
 {
-       if (this.spawnflags & SECRET_YES_SHOOT)
+       if (this.spawnflags & DOOR_SECRET_YES_SHOOT)
        {
                this.health = 10000;
                this.takedamage = DAMAGE_YES;
@@ -204,7 +198,10 @@ spawnfunc(func_door_secret)
        /*if (!this.deathtype) // map makers can override this
                this.deathtype = " got in the way";*/
 
-       if (!this.dmg) this.dmg = 2;
+       if (!this.dmg)
+       {
+               this.dmg = 2;
+       }
 
        // Magic formula...
        this.mangle = this.angles;
@@ -213,8 +210,35 @@ spawnfunc(func_door_secret)
        if (!InitMovingBrushTrigger(this)) return;
        this.effects |= EF_LOWPRECISION;
 
-       if (this.noise == "") this.noise = "misc/talk.wav";
+       // TODO: other soundpacks
+       if (this.sounds > 0)
+       {
+               this.noise1 = "plats/medplat1.wav";
+               this.noise2 = "plats/medplat1.wav";
+               this.noise3 = "plats/medplat2.wav";
+       }
+
+       // sound on touch
+       if (this.noise == "")
+       {
+               this.noise = "misc/talk.wav";
+       }
        precache_sound(this.noise);
+       // sound while moving backwards
+       if (this.noise1 && this.noise1 != "")
+       {
+               precache_sound(this.noise1);
+       }
+       // sound while moving sideways
+       if (this.noise2 && this.noise2 != "")
+       {
+               precache_sound(this.noise2);
+       }
+       // sound when door stops moving
+       if (this.noise3 && this.noise3 != "")
+       {
+               precache_sound(this.noise3);
+       }
 
        settouch(this, secret_touch);
        setblocked(this, secret_blocked);
@@ -224,9 +248,9 @@ spawnfunc(func_door_secret)
        {
        }
        else
-               this.spawnflags |= SECRET_YES_SHOOT;
+               this.spawnflags |= DOOR_SECRET_YES_SHOOT;
 
-       if (this.spawnflags & SECRET_YES_SHOOT)
+       if (this.spawnflags & DOOR_SECRET_YES_SHOOT)
        {
                //this.canteamdamage = true; // TODO
                this.health = 10000;
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..ee575bc424c2aa8bdc98da839badc986f362dd6e 100644 (file)
@@ -1 +1,8 @@
 #pragma once
+
+
+const int DOOR_SECRET_OPEN_ONCE = BIT(0); // stays open - LEGACY, set wait to -1 instead
+const int DOOR_SECRET_1ST_LEFT = BIT(1); // 1st move is left of arrow
+const int DOOR_SECRET_1ST_DOWN = BIT(2); // 1st move is down from arrow
+const int DOOR_SECRET_NO_SHOOT = BIT(3); // only opened by trigger
+const int DOOR_SECRET_YES_SHOOT = BIT(4); // shootable even if targeted
index 92f361a145c098c56efa037cc3b9ede05b3a9a4f..020ecca0855beb2260ad48608fd77bf917286b39 100644 (file)
@@ -126,8 +126,7 @@ spawnfunc(func_water)
 
 void func_ladder_remove(entity this)
 {
-       if(this.classname) { strunzone(this.classname); }
-       this.classname = string_null;
+       strfree(this.classname);
 }
 
 NET_HANDLE(ENT_CLIENT_LADDER, bool isnew)
index 9f97a1cea09b764d2021900fb011be0978254541..b052336217990a32a646d852679bc3c0d1d83c20 100644 (file)
@@ -58,12 +58,19 @@ void plat_link(entity this)
 
 spawnfunc(func_plat)
 {
-       if (this.sounds == 0) this.sounds = 2;
-
-    if (this.spawnflags & 4) this.dmg = 10000;
+       if (this.spawnflags & CRUSH)
+       {
+               this.dmg = 10000;
+       }
 
-    if (this.dmg && (this.message == "")) this.message = "was squished";
-    if (this.dmg && (this.message2 == "")) this.message2 = "was squished by";
+    if (this.dmg && (this.message == ""))
+       {
+               this.message = "was squished";
+       }
+    if (this.dmg && (this.message2 == ""))
+       {
+               this.message2 = "was squished by";
+       }
 
        if (this.sounds == 1)
        {
@@ -77,13 +84,20 @@ spawnfunc(func_plat)
                this.noise1 = "plats/medplat2.wav";
        }
 
+       // WARNING: backwards compatibility because people don't use already existing fields :(
        if (this.sound1)
                this.noise = this.sound1;
        if (this.sound2)
                this.noise1 = this.sound2;
 
-       if(this.noise && this.noise != "") { precache_sound(this.noise); }
-       if(this.noise1 && this.noise1 != "") { precache_sound(this.noise1); }
+       if(this.noise && this.noise != "")
+       {
+               precache_sound(this.noise);
+       }
+       if(this.noise1 && this.noise1 != "")
+       {
+               precache_sound(this.noise1);
+       }
 
        this.mangle = this.angles;
        this.angles = '0 0 0';
index 54fe212ae23ead1b7f8fce4f2f02c3845083d4c7..7de5a03ef8171e905ea0d7eff538580ad7e22f5e 100644 (file)
@@ -4,39 +4,39 @@ REGISTER_NET_LINKED(ENT_CLIENT_POINTPARTICLES)
 #ifdef SVQC
 // NOTE: also contains func_sparks
 
-bool pointparticles_SendEntity(entity this, entity to, float fl)
+bool pointparticles_SendEntity(entity this, entity to, float sendflags)
 {
        WriteHeader(MSG_ENTITY, ENT_CLIENT_POINTPARTICLES);
 
        // optional features to save space
-       fl = fl & 0x0F;
-       if(this.spawnflags & 2)
-               fl |= 0x10; // absolute count on toggle-on
+       sendflags = sendflags & 0x0F;
+       if(this.spawnflags & PARTICLES_IMPULSE)
+               sendflags |= SF_POINTPARTICLES_IMPULSE; // absolute count on toggle-on
        if(this.movedir != '0 0 0' || this.velocity != '0 0 0')
-               fl |= 0x20; // 4 bytes - saves CPU
+               sendflags |= SF_POINTPARTICLES_MOVING; // 4 bytes - saves CPU
        if(this.waterlevel || this.count != 1)
-               fl |= 0x40; // 4 bytes - obscure features almost never used
+               sendflags |= SF_POINTPARTICLES_JITTER_AND_COUNT; // 4 bytes - obscure features almost never used
        if(this.mins != '0 0 0' || this.maxs != '0 0 0')
-               fl |= 0x80; // 14 bytes - saves lots of space
+               sendflags |= SF_POINTPARTICLES_BOUNDS; // 14 bytes - saves lots of space
 
-       WriteByte(MSG_ENTITY, fl);
-       if(fl & 2)
+       WriteByte(MSG_ENTITY, sendflags);
+       if(sendflags & SF_TRIGGER_UPDATE)
        {
-               if(this.state)
+               if(this.active == ACTIVE_ACTIVE)
                        WriteCoord(MSG_ENTITY, this.impulse);
                else
                        WriteCoord(MSG_ENTITY, 0); // off
        }
-       if(fl & 4)
+       if(sendflags & SF_TRIGGER_RESET)
        {
                WriteVector(MSG_ENTITY, this.origin);
        }
-       if(fl & 1)
+       if(sendflags & SF_TRIGGER_INIT)
        {
                if(this.model != "null")
                {
                        WriteShort(MSG_ENTITY, this.modelindex);
-                       if(fl & 0x80)
+                       if(sendflags & SF_POINTPARTICLES_BOUNDS)
                        {
                                WriteVector(MSG_ENTITY, this.mins);
                                WriteVector(MSG_ENTITY, this.maxs);
@@ -45,19 +45,19 @@ bool pointparticles_SendEntity(entity this, entity to, float fl)
                else
                {
                        WriteShort(MSG_ENTITY, 0);
-                       if(fl & 0x80)
+                       if(sendflags & SF_POINTPARTICLES_BOUNDS)
                        {
                                WriteVector(MSG_ENTITY, this.maxs);
                        }
                }
                WriteShort(MSG_ENTITY, this.cnt);
                WriteString(MSG_ENTITY, this.mdl);
-               if(fl & 0x20)
+               if(sendflags & SF_POINTPARTICLES_MOVING)
                {
                        WriteShort(MSG_ENTITY, compressShortVector(this.velocity));
                        WriteShort(MSG_ENTITY, compressShortVector(this.movedir));
                }
-               if(fl & 0x40)
+               if(sendflags & SF_POINTPARTICLES_JITTER_AND_COUNT)
                {
                        WriteShort(MSG_ENTITY, this.waterlevel * 16.0);
                        WriteByte(MSG_ENTITY, this.count * 16.0);
@@ -80,30 +80,16 @@ bool pointparticles_SendEntity(entity this, entity to, float fl)
        return 1;
 }
 
-void pointparticles_use(entity this, entity actor, entity trigger)
-{
-       this.state = !this.state;
-       this.SendFlags |= 2;
-}
-
 void pointparticles_think(entity this)
 {
        if(this.origin != this.oldorigin)
        {
-               this.SendFlags |= 4;
+               this.SendFlags |= SF_TRIGGER_RESET;
                this.oldorigin = this.origin;
        }
        this.nextthink = time;
 }
 
-void pointparticles_reset(entity this)
-{
-       if(this.spawnflags & 1)
-               this.state = 1;
-       else
-               this.state = 0;
-}
-
 spawnfunc(func_pointparticles)
 {
        if(this.model != "") { precache_model(this.model); _setmodel(this, this.model); }
@@ -125,41 +111,35 @@ spawnfunc(func_pointparticles)
                setsize(this, '0 0 0', this.maxs - this.mins);
        }
        //if(!this.cnt) this.cnt = _particleeffectnum(this.mdl);
+       this.setactive = generic_netlinked_setactive;
 
-       Net_LinkEntity(this, (this.spawnflags & 4), 0, pointparticles_SendEntity);
+       Net_LinkEntity(this, (this.spawnflags & PARTICLES_VISCULLING), 0, pointparticles_SendEntity);
 
        IFTARGETED
        {
-               this.use = pointparticles_use;
-               this.reset = pointparticles_reset;
-               this.reset(this);
+               // backwards compatibility
+               this.use = generic_netlinked_legacy_use;
        }
-       else
-               this.state = 1;
+       this.reset = generic_netlinked_reset;
+       this.reset(this);
        setthink(this, pointparticles_think);
        this.nextthink = time;
 }
 
 spawnfunc(func_sparks)
 {
-       // this.cnt is the amount of sparks that one burst will spawn
-       if(this.cnt < 1) {
-               this.cnt = 25.0; // nice default value
+       if(this.count < 1) {
+               this.count = 25.0; // nice default value
        }
 
-       // this.wait is the probability that a sparkthink will spawn a spark shower
-       // range: 0 - 1, but 0 makes little sense, so...
-       if(this.wait < 0.05) {
-               this.wait = 0.25; // nice default value
+       if(this.impulse < 0.5) {
+               this.impulse = 2.5; // nice default value
        }
 
-       this.count = this.cnt;
        this.mins = '0 0 0';
        this.maxs = '0 0 0';
        this.velocity = '0 0 -1';
        this.mdl = "TE_SPARK";
-       this.impulse = 10 * this.wait; // by default 2.5/sec
-       this.wait = 0;
        this.cnt = 0; // use mdl
 
        spawnfunc_func_pointparticles(this);
@@ -169,17 +149,19 @@ spawnfunc(func_sparks)
 .int dphitcontentsmask;
 
 entityclass(PointParticles);
-class(PointParticles) .int cnt; // effect number
-class(PointParticles) .vector velocity; // particle velocity
-class(PointParticles) .float waterlevel; // direction jitter
-class(PointParticles) .int count; // count multiplier
-class(PointParticles) .int impulse; // density
-class(PointParticles) .string noise; // sound
-class(PointParticles) .float atten;
-class(PointParticles) .float volume;
-class(PointParticles) .float absolute; // 1 = count per second is absolute, 2 = only spawn at toggle
-class(PointParticles) .vector movedir; // trace direction
-class(PointParticles) .float glow_color; // palette index
+classfield(PointParticles) .int cnt; // effect number
+classfield(PointParticles) .vector velocity; // particle velocity
+classfield(PointParticles) .float waterlevel; // direction jitter
+classfield(PointParticles) .int count; // count multiplier
+classfield(PointParticles) .int impulse; // density
+classfield(PointParticles) .string noise; // sound
+classfield(PointParticles) .float atten;
+classfield(PointParticles) .float volume;
+classfield(PointParticles) .float absolute; // 1 = count per second is absolute, ABSOLUTE_ONLY_SPAWN_AT_TOGGLE = only spawn at toggle
+classfield(PointParticles) .vector movedir; // trace direction
+classfield(PointParticles) .float glow_color; // palette index
+
+const int ABSOLUTE_ONLY_SPAWN_AT_TOGGLE = 2;
 
 void Draw_PointParticles(entity this)
 {
@@ -190,7 +172,7 @@ void Draw_PointParticles(entity this)
        o = this.origin;
        sz = this.maxs - this.mins;
        n = doBGMScript(this);
-       if(this.absolute == 2)
+       if(this.absolute == ABSOLUTE_ONLY_SPAWN_AT_TOGGLE)
        {
                if(n >= 0)
                        n = this.just_toggled ? this.impulse : 0;
@@ -253,37 +235,31 @@ void Draw_PointParticles(entity this)
 
 void Ent_PointParticles_Remove(entity this)
 {
-       if(this.noise)
-               strunzone(this.noise);
-       this.noise = string_null;
-       if(this.bgmscript)
-               strunzone(this.bgmscript);
-       this.bgmscript = string_null;
-       if(this.mdl)
-               strunzone(this.mdl);
-       this.mdl = string_null;
+    strfree(this.noise);
+    strfree(this.bgmscript);
+    strfree(this.mdl);
 }
 
 NET_HANDLE(ENT_CLIENT_POINTPARTICLES, bool isnew)
 {
        float i;
        vector v;
-       int f = ReadByte();
-       if(f & 2)
+       int sendflags = ReadByte();
+       if(sendflags & SF_TRIGGER_UPDATE)
        {
                i = ReadCoord(); // density (<0: point, >0: volume)
                if(i && !this.impulse && (this.cnt || this.mdl)) // this.cnt check is so it only happens if the ent already existed
                        this.just_toggled = 1;
                this.impulse = i;
        }
-       if(f & 4)
+       if(sendflags & SF_TRIGGER_RESET)
        {
                this.origin = ReadVector();
        }
-       if(f & 1)
+       if(sendflags & SF_TRIGGER_INIT)
        {
                this.modelindex = ReadShort();
-               if(f & 0x80)
+               if(sendflags & SF_POINTPARTICLES_BOUNDS)
                {
                        if(this.modelindex)
                        {
@@ -304,7 +280,7 @@ NET_HANDLE(ENT_CLIENT_POINTPARTICLES, bool isnew)
                this.cnt = ReadShort(); // effect number
                this.mdl = strzone(ReadString()); // effect string
 
-               if(f & 0x20)
+               if(sendflags & SF_POINTPARTICLES_MOVING)
                {
                        this.velocity = decompressShortVector(ReadShort());
                        this.movedir = decompressShortVector(ReadShort());
@@ -313,7 +289,7 @@ NET_HANDLE(ENT_CLIENT_POINTPARTICLES, bool isnew)
                {
                        this.velocity = this.movedir = '0 0 0';
                }
-               if(f & 0x40)
+               if(sendflags & SF_POINTPARTICLES_JITTER_AND_COUNT)
                {
                        this.waterlevel = ReadShort() / 16.0;
                        this.count = ReadByte() / 16.0;
@@ -323,17 +299,13 @@ NET_HANDLE(ENT_CLIENT_POINTPARTICLES, bool isnew)
                        this.waterlevel = 0;
                        this.count = 1;
                }
-               if(this.noise)
-                       strunzone(this.noise);
-               if(this.bgmscript)
-                       strunzone(this.bgmscript);
-               this.noise = strzone(ReadString());
+               strcpy(this.noise, ReadString());
                if(this.noise != "")
                {
                        this.atten = ReadByte() / 64.0;
                        this.volume = ReadByte() / 255.0;
                }
-               this.bgmscript = strzone(ReadString());
+               strcpy(this.bgmscript, ReadString());
                if(this.bgmscript != "")
                {
                        this.bgmscriptattack = ReadByte() / 64.0;
@@ -346,18 +318,18 @@ NET_HANDLE(ENT_CLIENT_POINTPARTICLES, bool isnew)
 
        return = true;
 
-       if(f & 2)
+       if(sendflags & SF_TRIGGER_UPDATE)
        {
                this.absolute = (this.impulse >= 0);
                if(!this.absolute)
                {
                        v = this.maxs - this.mins;
-                       this.impulse *= -v.x * v.y * v.z / 262144; // relative: particles per 64^3 cube
+                       this.impulse *= -v.x * v.y * v.z / (64**3); // relative: particles per 64^3 cube
                }
        }
 
-       if(f & 0x10)
-               this.absolute = 2;
+       if(sendflags & SF_POINTPARTICLES_IMPULSE)
+               this.absolute = ABSOLUTE_ONLY_SPAWN_AT_TOGGLE;
 
        setorigin(this, this.origin);
        setsize(this, this.mins, this.maxs);
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..b167527bc813d91c0da4341704b2802048baa28d 100644 (file)
@@ -1 +1,11 @@
 #pragma once
+
+// spawnflags
+const int PARTICLES_IMPULSE = BIT(1);
+const int PARTICLES_VISCULLING = BIT(2);
+
+// sendflags
+const int SF_POINTPARTICLES_IMPULSE = BIT(4);
+const int SF_POINTPARTICLES_MOVING = BIT(5); // Send velocity and movedir
+const int SF_POINTPARTICLES_JITTER_AND_COUNT = BIT(6); // Send waterlevel (=jitter) and count
+const int SF_POINTPARTICLES_BOUNDS = BIT(7); // Send min and max of the brush
index 1817a9ce9a1e4d658b0b1f8411bc790734e62721..ff49eca2c0176c899cdaf1ccd02d9669e0fd851b 100644 (file)
@@ -38,17 +38,19 @@ spawnfunc(func_rain)
        this.solid = SOLID_NOT;
        SetBrushEntityModel(this);
        if (!this.cnt)
+       {
                this.cnt = 12;
+       }
        if (!this.count)
                this.count = 2000;
-       this.count = 0.01 * this.count * (this.size_x / 1024) * (this.size_y / 1024);
+       // relative to absolute particle count
+       this.count = this.count * (this.size_x / 1024) * (this.size_y / 1024);
        if (this.count < 1)
                this.count = 1;
        if(this.count > 65535)
                this.count = 65535;
 
-       this.state = 1; // 1 is rain, 0 is snow
-       this.Version = 1;
+       this.state = RAINSNOW_RAIN;
 
        Net_LinkEntity(this, false, 0, rainsnow_SendEntity);
 }
@@ -76,17 +78,19 @@ spawnfunc(func_snow)
        this.solid = SOLID_NOT;
        SetBrushEntityModel(this);
        if (!this.cnt)
+       {
                this.cnt = 12;
+       }
        if (!this.count)
                this.count = 2000;
-       this.count = 0.01 * this.count * (this.size_x / 1024) * (this.size_y / 1024);
+       // relative to absolute particle count
+       this.count = this.count * (this.size_x / 1024) * (this.size_y / 1024);
        if (this.count < 1)
                this.count = 1;
        if(this.count > 65535)
                this.count = 65535;
 
-       this.state = 0; // 1 is rain, 0 is snow
-       this.Version = 1;
+       this.state = RAINSNOW_SNOW;
 
        Net_LinkEntity(this, false, 0, rainsnow_SendEntity);
 }
@@ -113,11 +117,11 @@ void Draw_Snow(entity this)
 
 NET_HANDLE(ENT_CLIENT_RAINSNOW, bool isnew)
 {
-       this.impulse = ReadByte(); // Rain, Snow, or Whatever
+       this.state = ReadByte(); // Rain, Snow, or Whatever
        this.origin = ReadVector();
        this.maxs = ReadVector();
        this.velocity = decompressShortVector(ReadShort());
-       this.count = ReadShort() * 10;
+       this.count = ReadShort();
        this.glow_color = ReadByte(); // color
 
        return = true;
@@ -130,7 +134,7 @@ NET_HANDLE(ENT_CLIENT_RAINSNOW, bool isnew)
        setsize(this, this.mins, this.maxs);
        this.solid = SOLID_NOT;
        if (isnew) IL_PUSH(g_drawables, this);
-       if(this.impulse)
+       if(this.state == RAINSNOW_RAIN)
                this.draw = Draw_Rain;
        else
                this.draw = Draw_Snow;
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..d60eb4f481ea3bd764aa87325b9a2a125e2cb959 100644 (file)
@@ -1 +1,5 @@
 #pragma once
+
+
+const int RAINSNOW_SNOW = 0;
+const int RAINSNOW_RAIN = 1;
index 6268dcfeb86ea6f5fc7d9b981b7e22dd34240bc9..35351ee08e0a69a882a90ed7043ae18d8072c7e0 100644 (file)
@@ -1,6 +1,5 @@
 #include "rotating.qh"
 #ifdef SVQC
-const int FUNC_ROTATING_STARTOFF = BIT(4);
 
 void func_rotating_setactive(entity this, int astate)
 {
@@ -15,9 +14,18 @@ void func_rotating_setactive(entity this, int astate)
                this.active = astate;
 
        if(this.active  == ACTIVE_NOT)
+       {
                this.avelocity = '0 0 0';
+               stopsound(this, CH_AMBIENT_SINGLE);
+       }
        else
+       {
                this.avelocity = this.pos1;
+               if(this.noise && this.noise != "")
+               {
+                       _sound(this, CH_AMBIENT_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
+               }
+       }
 }
 
 void func_rotating_reset(entity this)
@@ -26,13 +34,20 @@ void func_rotating_reset(entity this)
 
        if(this.spawnflags & FUNC_ROTATING_STARTOFF)
        {
-               this.avelocity = '0 0 0';
-               this.active = ACTIVE_NOT;
+               this.setactive(this, ACTIVE_NOT);
        }
        else
        {
-               this.avelocity = this.pos1;
-               this.active = ACTIVE_ACTIVE;
+               this.setactive(this, ACTIVE_ACTIVE);
+       }
+}
+
+void func_rotating_init_for_player(entity this, entity player)
+{
+       if (this.noise && this.noise != "" && this.active == ACTIVE_ACTIVE && IS_REAL_CLIENT(player))
+       {
+               msg_entity = player;
+               soundto (MSG_ONE, this, CH_AMBIENT_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
        }
 }
 
@@ -46,37 +61,24 @@ dmgtime : See above.
 
 spawnfunc(func_rotating)
 {
-       if (this.noise != "")
+       if (this.noise && this.noise != "")
        {
                precache_sound(this.noise);
-               ambientsound(this.origin, this.noise, VOL_BASE, ATTEN_IDLE);
        }
 
        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 & BIT(2)) // X (untested)
+       if (this.spawnflags & FUNC_ROTATING_XAXIS)
                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 & BIT(3)) // Y (untested)
+       else if (this.spawnflags & FUNC_ROTATING_YAXIS)
                this.avelocity = '1 0 0' * this.speed;
-       // FIXME: test if this turns the right way, then remove this comment (negate as needed)
        else // Z
                this.avelocity = '0 1 0' * this.speed;
 
        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 == ""))
@@ -99,5 +101,10 @@ spawnfunc(func_rotating)
        setthink(this, SUB_NullThink); // for PushMove
 
        this.reset = func_rotating_reset;
+       this.reset(this);
+
+       // maybe send sound to new players
+       IL_PUSH(g_initforplayer, this);
+       this.init_for_player = func_rotating_init_for_player;
 }
 #endif
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..ad1b6ec920a2a319c99552ca051021984e9ffc64 100644 (file)
@@ -1 +1,6 @@
 #pragma once
+
+
+const int FUNC_ROTATING_XAXIS = BIT(2);
+const int FUNC_ROTATING_YAXIS = BIT(3);
+const int FUNC_ROTATING_STARTOFF = BIT(4);
index ead086708196889075c18ae958df185dccb02606..4e9c334562c97cc1bad305ccb2abf279a3d20fa4 100644 (file)
@@ -16,7 +16,7 @@ void train_wait(entity this)
                entity targ, cp;
                vector ang;
                targ = this.future_target;
-               if((this.spawnflags & 1) && targ.curvetarget)
+               if((this.spawnflags & TRAIN_CURVE) && targ.curvetarget)
                        cp = find(NULL, targetname, targ.curvetarget);
                else
                        cp = NULL;
@@ -43,7 +43,7 @@ void train_wait(entity this)
 
 #ifdef SVQC
        entity tg = this.future_target;
-       if(tg.spawnflags & 4)
+       if(tg.spawnflags & TRAIN_NEEDACTIVATION)
        {
                this.use = train_use;
                setthink(this, func_null);
@@ -91,7 +91,7 @@ void train_next(entity this)
        this.target_random = targ.target_random;
        this.future_target = train_next_find(targ);
 
-       if (this.spawnflags & 1)
+       if (this.spawnflags & TRAIN_CURVE)
        {
                if(targ.curvetarget)
                {
@@ -195,7 +195,7 @@ void train_use(entity this, entity actor, entity trigger)
 {
        this.nextthink = this.ltime + 1;
        setthink(this, train_next);
-       this.use = func_null; // not again
+       this.use = func_null; // not again, next target can set it again if needed
        if(trigger.target2 && trigger.target2 != "")
                this.future_target = find(NULL, targetname, trigger.target2);
 }
@@ -211,7 +211,7 @@ void func_train_find(entity this)
                objerror(this, "func_train_find: no next target");
        setorigin(this, targ.origin - this.view_ofs);
 
-       if(!(this.spawnflags & 4))
+       if(!(this.spawnflags & TRAIN_NEEDACTIVATION))
        {
                this.nextthink = this.ltime + 1;
                setthink(this, train_next);
@@ -242,10 +242,10 @@ spawnfunc(func_train)
                return;
        this.effects |= EF_LOWPRECISION;
 
-       if(this.spawnflags & 4)
+       if(this.spawnflags & TRAIN_NEEDACTIVATION)
                this.use = train_use;
 
-       if (this.spawnflags & 2)
+       if (this.spawnflags & TRAIN_TURN)
        {
                this.platmovetype_turn = true;
                this.view_ofs = '0 0 0'; // don't offset a rotating train, origin works differently now
index 8b6f7c02da22651e3f44884e76b9968d5a86c874..0b2a099c53576f46aff7a0968965b2dccccaad95 100644 (file)
@@ -1,5 +1,10 @@
 #pragma once
 
+
+const int TRAIN_CURVE = BIT(0);
+const int TRAIN_TURN = BIT(1);
+const int TRAIN_NEEDACTIVATION = BIT(2);
+
 #ifdef CSQC
 .float dmgtime;
 #endif
index 951a740a2024675371cd2e35412f8887adfe188e..61da52acbc483daef7c55c1e9d136000d7ace990 100644 (file)
@@ -6,20 +6,20 @@
 .float targetfactor, target2factor, target3factor, target4factor;
 .vector targetnormal, target2normal, target3normal, target4normal;
 
-vector func_vectormamamam_origin(entity o, float t)
+vector func_vectormamamam_origin(entity o, float timestep)
 {
        vector v, p;
-       float f;
+       float flags;
        entity e;
 
-       f = o.spawnflags;
+       flags = o.spawnflags;
        v = '0 0 0';
 
        e = o.wp00;
        if(e)
        {
-               p = e.origin + t * e.velocity;
-               if(f & 1)
+               p = e.origin + timestep * e.velocity;
+               if(flags & PROJECT_ON_TARGETNORMAL)
                        v = v + (p * o.targetnormal) * o.targetnormal * o.targetfactor;
                else
                        v = v + (p - (p * o.targetnormal) * o.targetnormal) * o.targetfactor;
@@ -28,8 +28,8 @@ vector func_vectormamamam_origin(entity o, float t)
        e = o.wp01;
        if(e)
        {
-               p = e.origin + t * e.velocity;
-               if(f & 2)
+               p = e.origin + timestep * e.velocity;
+               if(flags & PROJECT_ON_TARGET2NORMAL)
                        v = v + (p * o.target2normal) * o.target2normal * o.target2factor;
                else
                        v = v + (p - (p * o.target2normal) * o.target2normal) * o.target2factor;
@@ -38,8 +38,8 @@ vector func_vectormamamam_origin(entity o, float t)
        e = o.wp02;
        if(e)
        {
-               p = e.origin + t * e.velocity;
-               if(f & 4)
+               p = e.origin + timestep * e.velocity;
+               if(flags & PROJECT_ON_TARGET3NORMAL)
                        v = v + (p * o.target3normal) * o.target3normal * o.target3factor;
                else
                        v = v + (p - (p * o.target3normal) * o.target3normal) * o.target3factor;
@@ -48,8 +48,8 @@ vector func_vectormamamam_origin(entity o, float t)
        e = o.wp03;
        if(e)
        {
-               p = e.origin + t * e.velocity;
-               if(f & 8)
+               p = e.origin + timestep * e.velocity;
+               if(flags & PROJECT_ON_TARGET4NORMAL)
                        v = v + (p * o.target4normal) * o.target4normal * o.target4factor;
                else
                        v = v + (p - (p * o.target4normal) * o.target4normal) * o.target4factor;
@@ -60,7 +60,7 @@ vector func_vectormamamam_origin(entity o, float t)
 
 void func_vectormamamam_controller_think(entity this)
 {
-       this.nextthink = time + 0.1;
+       this.nextthink = time + vectormamamam_timestep;
 
        if(this.owner.active != ACTIVE_ACTIVE)
        {
@@ -69,7 +69,7 @@ void func_vectormamamam_controller_think(entity this)
        }
 
        if(this.owner.classname == "func_vectormamamam") // don't brake stuff if the func_vectormamamam was killtarget'ed
-               this.owner.velocity = (this.owner.destvec + func_vectormamamam_origin(this.owner, 0.1) - this.owner.origin) * 10;
+               this.owner.velocity = (this.owner.destvec + func_vectormamamam_origin(this.owner, vectormamamam_timestep) - this.owner.origin) * 10;
 }
 
 void func_vectormamamam_findtarget(entity this)
@@ -98,12 +98,45 @@ void func_vectormamamam_findtarget(entity this)
        setthink(controller, func_vectormamamam_controller_think);
 }
 
+void func_vectormamamam_setactive(entity this, int astate)
+{
+       if (astate == ACTIVE_TOGGLE)
+       {
+               if(this.active == ACTIVE_ACTIVE)
+                       this.active = ACTIVE_NOT;
+               else
+                       this.active = ACTIVE_ACTIVE;
+       }
+       else
+               this.active = astate;
+
+       if(this.active  == ACTIVE_NOT)
+       {
+               stopsound(this, CH_TRIGGER_SINGLE);
+       }
+       else
+       {
+               if(this.noise && this.noise != "")
+               {
+                       _sound(this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
+               }
+       }
+}
+
+void func_vectormamamam_init_for_player(entity this, entity player)
+{
+       if (this.noise && this.noise != "" && this.active == ACTIVE_ACTIVE && IS_REAL_CLIENT(player))
+       {
+               msg_entity = player;
+               soundto(MSG_ONE, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
+       }
+}
+
 spawnfunc(func_vectormamamam)
 {
        if (this.noise != "")
        {
                precache_sound(this.noise);
-               soundto(MSG_INIT, this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_IDLE);
        }
 
        if(!this.targetfactor)
@@ -139,9 +172,6 @@ spawnfunc(func_vectormamamam)
                this.dmgtime = 0.25;
        this.dmgtime2 = time;
 
-       if(this.netname == "")
-               this.netname = "1 0 0 0 1";
-
        if (!InitMovingBrushTrigger(this))
                return;
 
@@ -152,7 +182,12 @@ spawnfunc(func_vectormamamam)
        // Savage: Reduce bandwith, critical on e.g. nexdm02
        this.effects |= EF_LOWPRECISION;
 
-       this.active = ACTIVE_ACTIVE;
+       this.setactive = func_vectormamamam_setactive;
+       this.setactive(this, ACTIVE_ACTIVE);
+
+       // maybe send sound to new players
+       IL_PUSH(g_initforplayer, this);
+       this.init_for_player = func_vectormamamam_init_for_player;
 
        InitializeEntity(this, func_vectormamamam_findtarget, INITPRIO_FINDTARGET);
 }
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..7eb6b0a63b0f1be400212e81a94c1f41679cb2e5 100644 (file)
@@ -1 +1,9 @@
 #pragma once
+
+
+const int PROJECT_ON_TARGETNORMAL = BIT(0);
+const int PROJECT_ON_TARGET2NORMAL = BIT(1);
+const int PROJECT_ON_TARGET3NORMAL = BIT(2);
+const int PROJECT_ON_TARGET4NORMAL = BIT(3);
+
+const float vectormamamam_timestep = 0.1;
index 6c9093318f6bf827abfe5caf01b254a2115ee50a..a0f67b759b9981c72d7e2e27a5394479c111a275 100644 (file)
@@ -39,23 +39,12 @@ spawnfunc(path_corner)
 
 void corner_remove(entity this)
 {
-       if(this.target) { strunzone(this.target); }
-       this.target = string_null;
-
-       if(this.target2) { strunzone(this.target2); }
-       this.target2 = string_null;
-
-       if(this.target3) { strunzone(this.target3); }
-       this.target3 = string_null;
-
-       if(this.target4) { strunzone(this.target4); }
-       this.target4 = string_null;
-
-       if(this.targetname) { strunzone(this.targetname); }
-       this.targetname = string_null;
-
-       if(this.platmovetype) { strunzone(this.platmovetype); }
-       this.platmovetype = string_null;
+       strfree(this.target);
+       strfree(this.target2);
+       strfree(this.target3);
+       strfree(this.target4);
+       strfree(this.targetname);
+       strfree(this.platmovetype);
 }
 
 NET_HANDLE(ENT_CLIENT_CORNER, bool isnew)
index 63db2c18fa83ac172f62dce5a7b187fccc0c63c4..87619ca711097ff116907c36dc1a34acf0f3ddbd 100644 (file)
@@ -29,10 +29,10 @@ void follow_init(entity this)
                objerror(this, "follow: could not find target/killtarget");
                return;
        }
-       else if(this.spawnflags & 1)
+       else if(this.spawnflags & FOLLOW_ATTACH)
        {
                // attach
-               if(this.spawnflags & 2)
+               if(this.spawnflags & FOLLOW_LOCAL)
                {
                        setattachment(dst, src, this.message);
                }
@@ -46,7 +46,7 @@ void follow_init(entity this)
        }
        else
        {
-               if(this.spawnflags & 2)
+               if(this.spawnflags & FOLLOW_LOCAL)
                {
                        set_movetype(dst, MOVETYPE_FOLLOW);
                        dst.aiment = src;
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..aef491ff323bd00ab55269772d22e27451e5341e 100644 (file)
@@ -1 +1,5 @@
 #pragma once
+
+
+const int FOLLOW_ATTACH = BIT(0);
+const int FOLLOW_LOCAL = BIT(1);
index 3d5ef42d848bd7c745a7316690cb5271436baced..df88b750f245dbc7000deccd0a6785bf5ae1a300 100644 (file)
@@ -16,12 +16,12 @@ void misc_laser_aim(entity this)
        vector a;
        if(this.enemy)
        {
-               if(this.spawnflags & 2)
+               if(this.spawnflags & LASER_FINITE)
                {
                        if(this.enemy.origin != this.mangle)
                        {
                                this.mangle = this.enemy.origin;
-                               this.SendFlags |= 2;
+                               this.SendFlags |= SF_LASER_UPDATE_TARGET;
                        }
                }
                else
@@ -31,7 +31,7 @@ void misc_laser_aim(entity this)
                        if(a != this.mangle)
                        {
                                this.mangle = a;
-                               this.SendFlags |= 2;
+                               this.SendFlags |= SF_LASER_UPDATE_TARGET;
                        }
                }
        }
@@ -40,12 +40,12 @@ void misc_laser_aim(entity this)
                if(this.angles != this.mangle)
                {
                        this.mangle = this.angles;
-                       this.SendFlags |= 2;
+                       this.SendFlags |= SF_LASER_UPDATE_TARGET;
                }
        }
        if(this.origin != this.oldorigin)
        {
-               this.SendFlags |= 1;
+               this.SendFlags |= SF_LASER_UPDATE_ORIGIN;
                this.oldorigin = this.origin;
        }
 }
@@ -65,7 +65,7 @@ void misc_laser_think(entity this)
 
        this.nextthink = time;
 
-       if(!this.state)
+       if(this.active == ACTIVE_NOT)
                return;
 
        misc_laser_aim(this);
@@ -73,13 +73,13 @@ void misc_laser_think(entity this)
        if(this.enemy)
        {
                o = this.enemy.origin;
-               if (!(this.spawnflags & 2))
-                       o = this.origin + normalize(o - this.origin) * 32768;
+               if (!(this.spawnflags & LASER_FINITE))
+                       o = this.origin + normalize(o - this.origin) * LASER_BEAM_MAXLENGTH;
        }
        else
        {
                makevectors(this.mangle);
-               o = this.origin + v_forward * 32768;
+               o = this.origin + v_forward * LASER_BEAM_MAXLENGTH;
        }
 
        if(this.dmg || this.enemy.target != "")
@@ -115,48 +115,48 @@ void misc_laser_think(entity this)
        if(this.dmg)
        {
                if(this.team)
-                       if(((this.spawnflags & 8) == 0) == (this.team != hitent.team))
+                       if(((this.spawnflags & LASER_INVERT_TEAM) == 0) == (this.team != hitent.team))
                                return;
                if(hitent.takedamage)
                        Damage(hitent, this, this, ((this.dmg < 0) ? 100000 : (this.dmg * frametime)), DEATH_HURTTRIGGER.m_id, DMG_NOWEP, hitloc, '0 0 0');
        }
 }
 
-bool laser_SendEntity(entity this, entity to, float fl)
+bool laser_SendEntity(entity this, entity to, float sendflags)
 {
        WriteHeader(MSG_ENTITY, ENT_CLIENT_LASER);
-       fl = fl - (fl & 0xF0); // use that bit to indicate finite length laser
-       if(this.spawnflags & 2)
-               fl |= 0x80;
+       sendflags = sendflags & 0x0F; // use that bit to indicate finite length laser
+       if(this.spawnflags & LASER_FINITE)
+               sendflags |= SF_LASER_FINITE;
        if(this.alpha)
-               fl |= 0x40;
+               sendflags |= SF_LASER_ALPHA;
        if(this.scale != 1 || this.modelscale != 1)
-               fl |= 0x20;
-       if(this.spawnflags & 4)
-               fl |= 0x10;
-       WriteByte(MSG_ENTITY, fl);
-       if(fl & 1)
+               sendflags |= SF_LASER_SCALE;
+       if(this.spawnflags & LASER_NOTRACE)
+               sendflags |= SF_LASER_NOTRACE;
+       WriteByte(MSG_ENTITY, sendflags);
+       if(sendflags & SF_LASER_UPDATE_ORIGIN)
        {
                WriteVector(MSG_ENTITY, this.origin);
        }
-       if(fl & 8)
+       if(sendflags & SF_LASER_UPDATE_EFFECT)
        {
-               WriteByte(MSG_ENTITY, this.colormod_x * 255.0);
-               WriteByte(MSG_ENTITY, this.colormod_y * 255.0);
-               WriteByte(MSG_ENTITY, this.colormod_z * 255.0);
-               if(fl & 0x40)
+               WriteByte(MSG_ENTITY, this.beam_color.x * 255.0);
+               WriteByte(MSG_ENTITY, this.beam_color.y * 255.0);
+               WriteByte(MSG_ENTITY, this.beam_color.z * 255.0);
+               if(sendflags & SF_LASER_ALPHA)
                        WriteByte(MSG_ENTITY, this.alpha * 255.0);
-               if(fl & 0x20)
+               if(sendflags & SF_LASER_SCALE)
                {
                        WriteByte(MSG_ENTITY, bound(0, this.scale * 16.0, 255));
                        WriteByte(MSG_ENTITY, bound(0, this.modelscale * 16.0, 255));
                }
-               if((fl & 0x80) || !(fl & 0x10)) // effect doesn't need sending if the laser is infinite and has collision testing turned off
-                       WriteShort(MSG_ENTITY, this.cnt + 1);
+               if((sendflags & SF_LASER_FINITE) || !(sendflags & SF_LASER_NOTRACE)) // effect doesn't need sending if the laser is infinite and has collision testing turned off
+                       WriteShort(MSG_ENTITY, this.cnt);
        }
-       if(fl & 2)
+       if(sendflags & SF_LASER_UPDATE_TARGET)
        {
-               if(fl & 0x80)
+               if(sendflags & SF_LASER_FINITE)
                {
                        WriteVector(MSG_ENTITY, this.enemy.origin);
                }
@@ -166,9 +166,9 @@ bool laser_SendEntity(entity this, entity to, float fl)
                        WriteAngle(MSG_ENTITY, this.mangle_y);
                }
        }
-       if(fl & 4)
-               WriteByte(MSG_ENTITY, this.state);
-       return 1;
+       if(sendflags & SF_LASER_UPDATE_ACTIVE)
+               WriteByte(MSG_ENTITY, this.active);
+       return true;
 }
 
 /*QUAKED spawnfunc_misc_laser (.5 .5 .5) ? START_ON DEST_IS_FIXED
@@ -178,24 +178,41 @@ Keys:
  spawnfunc_target_position where the laser ends
 "mdl"
  name of beam end effect to use
-"colormod"
+"beam_color"
  color of the beam (default: red)
 "dmg"
  damage per second (-1 for a laser that kills immediately)
 */
-void laser_use(entity this, entity actor, entity trigger)
+
+void laser_setactive(entity this, int act)
 {
-       this.state = !this.state;
-       this.SendFlags |= 4;
-       misc_laser_aim(this);
+       int old_status = this.active;
+       if(act == ACTIVE_TOGGLE)
+       {
+               if(this.active == ACTIVE_ACTIVE)
+               {
+                       this.active = ACTIVE_NOT;
+               }
+               else
+               {
+                       this.active = ACTIVE_ACTIVE;
+               }
+       }
+       else
+       {
+               this.active = act;
+       }
+
+       if (this.active != old_status)
+       {
+               this.SendFlags |= SF_LASER_UPDATE_ACTIVE;
+               misc_laser_aim(this);
+       }
 }
 
-void laser_reset(entity this)
+void laser_use(entity this, entity actor, entity trigger)
 {
-       if(this.spawnflags & 1)
-               this.state = 1;
-       else
-               this.state = 0;
+       this.setactive(this, ACTIVE_TOGGLE);
 }
 
 spawnfunc(misc_laser)
@@ -221,14 +238,38 @@ spawnfunc(misc_laser)
        if(this.cnt < 0)
                this.cnt = -1;
 
-       if(this.colormod == '0 0 0')
+       if(!this.beam_color && this.colormod)
+       {
+               LOG_WARN("misc_laser uses legacy field 'colormod', please use 'beam_color' instead");
+               this.beam_color = this.colormod;
+       }
+
+       if(this.beam_color == '0 0 0')
+       {
                if(!this.alpha)
-                       this.colormod = '1 0 0';
-       if(this.message == "") this.message = "saw the light";
-       if (this.message2 == "") this.message2 = "was pushed into a laser by";
-       if(!this.scale) this.scale = 1;
-       if(!this.modelscale) this.modelscale = 1;
-       else if(this.modelscale < 0) this.modelscale = 0;
+                       this.beam_color = '1 0 0';
+       }
+
+       if(this.message == "")
+       {
+               this.message = "saw the light";
+       }
+       if (this.message2 == "")
+       {
+               this.message2 = "was pushed into a laser by";
+       }
+       if(!this.scale)
+       {
+               this.scale = 1;
+       }
+       if(!this.modelscale)
+       {
+               this.modelscale = 1;
+       }
+       else if(this.modelscale < 0)
+       {
+               this.modelscale = 0;
+       }
        setthink(this, misc_laser_think);
        this.nextthink = time;
        InitializeEntity(this, misc_laser_init, INITPRIO_FINDTARGET);
@@ -237,38 +278,40 @@ spawnfunc(misc_laser)
 
        Net_LinkEntity(this, false, 0, laser_SendEntity);
 
+       this.setactive = laser_setactive;
+
        IFTARGETED
        {
-               this.reset = laser_reset;
-               this.reset(this);
+               // backwards compatibility
                this.use = laser_use;
        }
-       else
-               this.state = 1;
+
+       this.reset = generic_netlinked_reset;
+       this.reset(this);
 }
 #elif defined(CSQC)
 
 // a laser goes from origin in direction angles
-// it has color 'colormod'
+// it has color 'beam_color'
 // and stops when something is in the way
 entityclass(Laser);
-class(Laser) .int cnt; // end effect
-class(Laser) .vector colormod;
-class(Laser) .int state; // on-off
-class(Laser) .int count; // flags for the laser
-class(Laser) .vector velocity;
-class(Laser) .float alpha;
-class(Laser) .float scale; // scaling factor of the thickness
-class(Laser) .float modelscale; // scaling factor of the dlight
+classfield(Laser) .int cnt; // end effect
+classfield(Laser) .vector colormod;
+classfield(Laser) .int state; // on-off
+classfield(Laser) .int count; // flags for the laser
+classfield(Laser) .vector velocity; // laser endpoint if it is FINITE
+classfield(Laser) .float alpha;
+classfield(Laser) .float scale; // scaling factor of the thickness
+classfield(Laser) .float modelscale; // scaling factor of the dlight
 
 void Draw_Laser(entity this)
 {
-       if(!this.state)
+       if(this.active == ACTIVE_NOT)
                return;
        InterpolateOrigin_Do(this);
-       if(this.count & 0x80)
+       if(this.count & SF_LASER_FINITE)
        {
-               if(this.count & 0x10)
+               if(this.count & SF_LASER_NOTRACE)
                {
                        trace_endpos = this.velocity;
                        trace_dphitq3surfaceflags = 0;
@@ -278,37 +321,37 @@ void Draw_Laser(entity this)
        }
        else
        {
-               if(this.count & 0x10)
+               if(this.count & SF_LASER_NOTRACE)
                {
                        makevectors(this.angles);
-                       trace_endpos = this.origin + v_forward * 1048576;
+                       trace_endpos = this.origin + v_forward * LASER_BEAM_MAXWORLDSIZE;
                        trace_dphitq3surfaceflags = Q3SURFACEFLAG_SKY;
                }
                else
                {
                        makevectors(this.angles);
-                       traceline(this.origin, this.origin + v_forward * 32768, 0, this);
+                       traceline(this.origin, this.origin + v_forward * LASER_BEAM_MAXLENGTH, 0, this);
                        if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
-                               trace_endpos = this.origin + v_forward * 1048576;
+                               trace_endpos = this.origin + v_forward * LASER_BEAM_MAXWORLDSIZE;
                }
        }
        if(this.scale != 0)
        {
                if(this.alpha)
                {
-                       Draw_CylindricLine(this.origin, trace_endpos, this.scale, "particles/laserbeam", 0, time * 3, this.colormod, this.alpha, DRAWFLAG_NORMAL, view_origin);
+                       Draw_CylindricLine(this.origin, trace_endpos, this.scale, "particles/laserbeam", 0, time * 3, this.beam_color, this.alpha, DRAWFLAG_NORMAL, view_origin);
                }
                else
                {
-                       Draw_CylindricLine(this.origin, trace_endpos, this.scale, "particles/laserbeam", 0, time * 3, this.colormod, 0.5, DRAWFLAG_ADDITIVE, view_origin);
+                       Draw_CylindricLine(this.origin, trace_endpos, this.scale, "particles/laserbeam", 0, time * 3, this.beam_color, 0.5, DRAWFLAG_ADDITIVE, view_origin);
                }
        }
        if (!(trace_dphitq3surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NOIMPACT)))
        {
                if(this.cnt >= 0)
                        __pointparticles(this.cnt, trace_endpos, trace_plane_normal, drawframetime * 1000);
-               if(this.colormod != '0 0 0' && this.modelscale != 0)
-                       adddynamiclight(trace_endpos + trace_plane_normal * 1, this.modelscale, this.colormod * 5);
+               if(this.beam_color != '0 0 0' && this.modelscale != 0)
+                       adddynamiclight(trace_endpos + trace_plane_normal * 1, this.modelscale, this.beam_color * 5);
        }
 }
 
@@ -317,43 +360,43 @@ NET_HANDLE(ENT_CLIENT_LASER, bool isnew)
        InterpolateOrigin_Undo(this);
 
        // 30 bytes, or 13 bytes for just moving
-       int f = ReadByte();
-       this.count = (f & 0xF0);
+       int sendflags = ReadByte();
+       this.count = (sendflags & 0xF0);
 
-       if(this.count & 0x80)
+       if(this.count & SF_LASER_FINITE)
                this.iflags = IFLAG_VELOCITY | IFLAG_ORIGIN;
        else
                this.iflags = IFLAG_ANGLES | IFLAG_ORIGIN;
 
-       if(f & 1)
+       if(sendflags & SF_LASER_UPDATE_ORIGIN)
        {
                this.origin = ReadVector();
                setorigin(this, this.origin);
        }
-       if(f & 8)
+       if(sendflags & SF_LASER_UPDATE_EFFECT)
        {
-               this.colormod_x = ReadByte() / 255.0;
-               this.colormod_y = ReadByte() / 255.0;
-               this.colormod_z = ReadByte() / 255.0;
-               if(f & 0x40)
+               this.beam_color.x = ReadByte() / 255.0;
+               this.beam_color.y = ReadByte() / 255.0;
+               this.beam_color.z = ReadByte() / 255.0;
+               if(sendflags & SF_LASER_ALPHA)
                        this.alpha = ReadByte() / 255.0;
                else
                        this.alpha = 0;
-               this.scale = 2;
-               this.modelscale = 50;
-               if(f & 0x20)
+               this.scale = 2; // NOTE: why 2?
+               this.modelscale = 50; // NOTE: why 50?
+               if(sendflags & SF_LASER_SCALE)
                {
                        this.scale *= ReadByte() / 16.0; // beam radius
                        this.modelscale *= ReadByte() / 16.0; // dlight radius
                }
-               if((f & 0x80) || !(f & 0x10))
-                       this.cnt = ReadShort() - 1; // effect number
+               if((sendflags & SF_LASER_FINITE) || !(sendflags & SF_LASER_NOTRACE))
+                       this.cnt = ReadShort(); // effect number
                else
                        this.cnt = 0;
        }
-       if(f & 2)
+       if(sendflags & SF_LASER_UPDATE_TARGET)
        {
-               if(f & 0x80)
+               if(sendflags & SF_LASER_FINITE)
                {
                        this.velocity = ReadVector();
                }
@@ -363,8 +406,8 @@ NET_HANDLE(ENT_CLIENT_LASER, bool isnew)
                        this.angles_y = ReadAngle();
                }
        }
-       if(f & 4)
-               this.state = ReadByte();
+       if(sendflags & SF_LASER_UPDATE_ACTIVE)
+               this.active = ReadByte();
 
        return = true;
 
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..0ff57646ad760e1c3b8b884bec49c4b53b800ea3 100644 (file)
@@ -1 +1,22 @@
 #pragma once
+
+
+const int LASER_FINITE = BIT(1);
+const int LASER_NOTRACE = BIT(2);
+const int LASER_INVERT_TEAM = BIT(3);
+
+const int SF_LASER_UPDATE_ORIGIN = BIT(0);
+const int SF_LASER_UPDATE_TARGET = BIT(1);
+const int SF_LASER_UPDATE_ACTIVE = BIT(2);
+const int SF_LASER_UPDATE_EFFECT = BIT(3);
+
+const int SF_LASER_NOTRACE = BIT(4);
+const int SF_LASER_SCALE = BIT(5);
+const int SF_LASER_ALPHA = BIT(6);
+const int SF_LASER_FINITE = BIT(7);
+
+.vector beam_color;
+
+const float LASER_BEAM_MAXLENGTH = 32768; // maximum length of a beam trace
+// TODO: find a better way to do this
+const float LASER_BEAM_MAXWORLDSIZE = 1048576; // to make sure the endpoint of the beam is not visible inside
index 40c7d46c42803ce65dc2411a5da2847d190791b0..126a20ea26ec08e254c1ee6e9d9473479b084dda 100644 (file)
@@ -3,12 +3,12 @@ REGISTER_NET_LINKED(ENT_CLIENT_TELEPORT_DEST)
 
 #ifdef SVQC
 
-bool teleport_dest_send(entity this, entity to, int sf)
+bool teleport_dest_send(entity this, entity to, int sendflags)
 {
        WriteHeader(MSG_ENTITY, ENT_CLIENT_TELEPORT_DEST);
-       WriteByte(MSG_ENTITY, sf);
+       WriteByte(MSG_ENTITY, sendflags);
 
-       if(sf & 1)
+       if(sendflags & SF_TRIGGER_INIT)
        {
                WriteByte(MSG_ENTITY, this.cnt);
                WriteCoord(MSG_ENTITY, this.speed);
@@ -26,7 +26,7 @@ bool teleport_dest_send(entity this, entity to, int sf)
 void teleport_dest_link(entity this)
 {
        Net_LinkEntity(this, false, 0, teleport_dest_send);
-       this.SendFlags |= 1; // update
+       this.SendFlags |= SF_TRIGGER_INIT;
 }
 
 spawnfunc(info_teleport_destination)
@@ -57,20 +57,15 @@ spawnfunc(misc_teleporter_dest)
 
 void teleport_dest_remove(entity this)
 {
-       //if(this.classname)
-               //strunzone(this.classname);
-       //this.classname = string_null;
-
-       if(this.targetname)
-               strunzone(this.targetname);
-       this.targetname = string_null;
+    // strfree(this.classname);
+    strfree(this.targetname);
 }
 
 NET_HANDLE(ENT_CLIENT_TELEPORT_DEST, bool isnew)
 {
-       int sf = ReadByte();
+       int sendflags = ReadByte();
 
-       if(sf & 1)
+       if(sendflags & SF_TRIGGER_INIT)
        {
                this.classname = "info_teleport_destination";
                this.cnt = ReadByte();
index 8ea48275d36b8d0f5d5ce9c98aacdfdf1d2a746d..4747877314a3ac52f78c30c06233ec3f63dcf170 100644 (file)
@@ -61,7 +61,7 @@ void plat_spawn_inside_trigger(entity this)
 void plat_hit_top(entity this)
 {
        _sound (this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
-       this.state = 1;
+       this.state = STATE_TOP;
 
        setthink(this, plat_go_down);
        this.nextthink = this.ltime + 3;
@@ -70,20 +70,20 @@ void plat_hit_top(entity this)
 void plat_hit_bottom(entity this)
 {
        _sound (this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
-       this.state = 2;
+       this.state = STATE_BOTTOM;
 }
 
 void plat_go_down(entity this)
 {
        _sound (this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_NORM);
-       this.state = 3;
+       this.state = STATE_DOWN;
        SUB_CalcMove (this, this.pos2, TSPEED_LINEAR, this.speed, plat_hit_bottom);
 }
 
 void plat_go_up(entity this)
 {
        _sound (this, CH_TRIGGER_SINGLE, this.noise, VOL_BASE, ATTEN_NORM);
-       this.state = 4;
+       this.state = STATE_UP;
        SUB_CalcMove (this, this.pos1, TSPEED_LINEAR, this.speed, plat_hit_top);
 }
 
@@ -102,9 +102,9 @@ void plat_center_touch(entity this, entity toucher)
                return;
 #endif
 
-       if (this.enemy.state == 2) {
+       if (this.enemy.state == STATE_BOTTOM) {
                plat_go_up(this.enemy);
-       } else if (this.enemy.state == 1)
+       } else if (this.enemy.state == STATE_TOP)
                this.enemy.nextthink = this.enemy.ltime + 1;
 }
 
@@ -121,7 +121,7 @@ void plat_outside_touch(entity this, entity toucher)
                return;
 #endif
 
-       if (this.enemy.state == 1) {
+       if (this.enemy.state == STATE_TOP) {
            entity e = this.enemy;
                plat_go_down(e);
     }
@@ -137,7 +137,7 @@ void plat_trigger_use(entity this, entity actor, entity trigger)
 
 void plat_crush(entity this, entity blocker)
 {
-       if((this.spawnflags & 4) && (blocker.takedamage != DAMAGE_NO))
+       if((this.spawnflags & CRUSH) && (blocker.takedamage != DAMAGE_NO))
        { // KIll Kill Kill!!
 #ifdef SVQC
                Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
@@ -155,9 +155,9 @@ void plat_crush(entity this, entity blocker)
                }
 #endif
 
-               if (this.state == 4)
+               if (this.state == STATE_UP)
                        plat_go_down (this);
-               else if (this.state == 3)
+               else if (this.state == STATE_DOWN)
                        plat_go_up (this);
        // when in other states, then the plat_crush event came delayed after
        // plat state already had changed
@@ -168,11 +168,13 @@ void plat_crush(entity this, entity blocker)
 void plat_use(entity this, entity actor, entity trigger)
 {
        this.use = func_null;
-       if (this.state != 4)
+       if (this.state != STATE_UP)
                objerror (this, "plat_use: not in up state");
        plat_go_down(this);
 }
 
+// WARNING: backwards compatibility because people don't use already existing fields :(
+// TODO: Check if any maps use these fields and remove these fields if it doesn't break maps
 .string sound1, sound2;
 
 void plat_reset(entity this)
@@ -180,13 +182,13 @@ void plat_reset(entity this)
        IFTARGETED
        {
                setorigin(this, this.pos1);
-               this.state = 4;
+               this.state = STATE_UP;
                this.use = plat_use;
        }
        else
        {
                setorigin(this, this.pos2);
-               this.state = 2;
+               this.state = STATE_BOTTOM;
                this.use = plat_trigger_use;
        }
 
index c40467494f367adf9c68af7390dbd55ee6ec120c..346cebc7163dfade8657cba5caa5e3cc455838c6 100644 (file)
@@ -1,5 +1,8 @@
 #pragma once
 
+
+const int PLAT_LOW_TRIGGER = BIT(0);
+
 .float dmgtime2;
 
 void plat_center_touch(entity this, entity toucher);
@@ -8,6 +11,5 @@ void plat_trigger_use(entity this, entity actor, entity trigger);
 void plat_go_up(entity this);
 void plat_go_down(entity this);
 void plat_crush(entity this, entity blocker);
-const float PLAT_LOW_TRIGGER = 1;
 
 .float dmg;
index 5b6182e0ab8574877e11f8432a316bcf41e94aa3..2a237fdcb79abdb5be234fd7e65b0dd4512134c4 100644 (file)
@@ -145,6 +145,8 @@ void SUB_CalcMove_controller_think (entity this)
                // derivative: delta + 2 * delta2 (e.g. for angle positioning)
                entity own = this.owner;
                setthink(own, this.think1);
+               // set the owner's reference to this entity to NULL
+               own.move_controller = NULL;
                delete(this);
                getthink(own)(own);
        }
@@ -220,8 +222,14 @@ void SUB_CalcMove_Bezier (entity this, vector tcontrol, vector tdest, float tspe
                return;
        }
 
+       // delete the previous controller, otherwise changing movement midway is glitchy
+       if (this.move_controller != NULL)
+       {
+               delete(this.move_controller);
+       }
        controller = new(SUB_CalcMove_controller);
        controller.owner = this;
+       this.move_controller = controller;
        controller.platmovetype = this.platmovetype;
        controller.platmovetype_start = this.platmovetype_start;
        controller.platmovetype_end = this.platmovetype_end;
index 1b3bc5e690d438f6eeb1b0bf228eab6efd7ee75a..8d4e406504cf62eadd2458b01912eb938c5c51bc 100644 (file)
@@ -1,4 +1,5 @@
 #pragma once
+#include "defs.qh"
 
 void SUB_SetFade (entity ent, float when, float fading_time);
 void SUB_VanishOrRemove (entity ent);
@@ -41,17 +42,14 @@ void SUB_VanishOrRemove (entity ent);
 
 .vector dest1, dest2;
 
+.entity move_controller;
+
 #ifdef CSQC
 // this stuff is defined in the server side engine VM, so we must define it separately here
 .float takedamage;
-const float DAMAGE_NO  = 0;
-const float DAMAGE_YES = 1;
-const float DAMAGE_AIM = 2;
-
-float  STATE_TOP               = 0;
-float  STATE_BOTTOM    = 1;
-float  STATE_UP                = 2;
-float  STATE_DOWN              = 3;
+const int DAMAGE_NO = 0;
+const int DAMAGE_YES = 1;
+const int DAMAGE_AIM = 2;
 
 .string                noise, noise1, noise2, noise3;  // contains names of wavs to play
 
index 6c006d42a91610e70cd3984bc076cdc61312885c..114fd871818a14e4ea3df07f52584aa88802ec65 100644 (file)
@@ -5,7 +5,7 @@
 
 void target_changelevel_use(entity this, entity actor, entity trigger)
 {
-       if(this.spawnflags & 2)
+       if(this.spawnflags & CHANGELEVEL_MULTIPLAYER)
        {
                // simply don't react if a non-player triggers it
                if(!IS_PLAYER(actor)) { return; }
@@ -33,10 +33,23 @@ void target_changelevel_use(entity this, entity actor, entity trigger)
                localcmd(strcat("changelevel ", this.chmap, "\n"));
 }
 
+/*target_changelevel
+Target to change/end level
+KEYS:
+chmap: map to switch to, leave empty for endmatch
+gametype: gametype for the next map
+count: fraction of real players that need to trigger this entity for levelchange
+SPAWNFLAGS:
+CHANGELEVEL_MULTIPLAYER: multiplayer support
+*/
+
 spawnfunc(target_changelevel)
 {
        this.use = target_changelevel_use;
 
-       if(!this.count) { this.count = 0.7; }
+       if(!this.count)
+       {
+               this.count = 0.7;
+       }
 }
 #endif
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..f6e206edc9a4f52ecc4b7a0d53ca07764563fd54 100644 (file)
@@ -1 +1,4 @@
 #pragma once
+
+
+const int CHANGELEVEL_MULTIPLAYER = BIT(1);
index 6cef53d6e558c5fe76aaae3bcfa7a9fece1ce90c..21419cf81a1e52c8ae056b02f1f81704d9d12249 100644 (file)
@@ -14,6 +14,8 @@ void target_levelwarp_use(entity this, entity actor, entity trigger)
 
 spawnfunc(target_levelwarp)
 {
+       // this.cnt is index (starting from 1) of the campaign level to warp to
+       // 0 means next level
        this.use = target_levelwarp_use;
 }
 #endif
index 7ec3351381b6265b0d24e4e16c02caa80d32fe2d..5a63872dbd6c46b6742b3534be7b4531c0d38ef2 100644 (file)
@@ -14,7 +14,10 @@ REGISTER_NET_LINKED(ENT_CLIENT_TRIGGER_MUSIC)
 #ifdef SVQC
 
 IntrusiveList g_targetmusic_list;
-STATIC_INIT(g_targetmusic_list) { g_targetmusic_list = IL_NEW(); }
+STATIC_INIT(g_targetmusic_list)
+{
+       g_targetmusic_list = IL_NEW();
+}
 
 // values:
 //   volume
@@ -37,7 +40,10 @@ void target_music_sendto(entity this, int to, bool is)
 }
 void target_music_reset(entity this)
 {
-       if (this.targetname == "") target_music_sendto(this, MSG_ALL, 1);
+       if (this.targetname == "")
+       {
+               target_music_sendto(this, MSG_ALL, true);
+       }
 }
 void target_music_kill()
 {
@@ -45,9 +51,9 @@ void target_music_kill()
        {
                it.volume = 0;
         if (it.targetname == "")
-            target_music_sendto(it, MSG_ALL, 1);
+            target_music_sendto(it, MSG_ALL, true);
         else
-            target_music_sendto(it, MSG_ALL, 0);
+            target_music_sendto(it, MSG_ALL, false);
        });
 }
 void target_music_use(entity this, entity actor, entity trigger)
@@ -57,11 +63,11 @@ void target_music_use(entity this, entity actor, entity trigger)
        if(IS_REAL_CLIENT(actor))
        {
                msg_entity = actor;
-               target_music_sendto(this, MSG_ONE, 1);
+               target_music_sendto(this, MSG_ONE, true);
        }
        FOREACH_CLIENT(IS_SPEC(it) && it.enemy == actor, {
                msg_entity = it;
-               target_music_sendto(this, MSG_ONE, 1);
+               target_music_sendto(this, MSG_ONE, true);
        });
 }
 spawnfunc(target_music)
@@ -72,18 +78,18 @@ spawnfunc(target_music)
                this.volume = 1;
        IL_PUSH(g_targetmusic_list, this);
        if(this.targetname == "")
-               target_music_sendto(this, MSG_INIT, 1);
+               target_music_sendto(this, MSG_INIT, true);
        else
-               target_music_sendto(this, MSG_INIT, 0);
+               target_music_sendto(this, MSG_INIT, false);
 }
 void TargetMusic_RestoreGame()
 {
        IL_EACH(g_targetmusic_list, true,
        {
                if(it.targetname == "")
-                       target_music_sendto(it, MSG_INIT, 1);
+                       target_music_sendto(it, MSG_INIT, true);
                else
-                       target_music_sendto(it, MSG_INIT, 0);
+                       target_music_sendto(it, MSG_INIT, false);
        });
 }
 // values:
@@ -92,20 +98,17 @@ void TargetMusic_RestoreGame()
 //   targetname
 //   fade_time
 // spawnflags:
-//   1 = START_OFF
-// when triggered, it is disabled/enabled for everyone
-bool trigger_music_SendEntity(entity this, entity to, float sf)
+//   START_DISABLED
+// can be disabled/enabled for everyone with relays
+bool trigger_music_SendEntity(entity this, entity to, int sendflags)
 {
        WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_MUSIC);
-       sf &= ~0x80;
-       if(this.cnt)
-               sf |= 0x80;
-       WriteByte(MSG_ENTITY, sf);
-       if(sf & 4)
+       WriteByte(MSG_ENTITY, sendflags);
+       if(sendflags & SF_MUSIC_ORIGIN)
        {
                WriteVector(MSG_ENTITY, this.origin);
        }
-       if(sf & 1)
+       if(sendflags & SF_TRIGGER_INIT)
        {
                if(this.model != "null")
                {
@@ -123,31 +126,44 @@ bool trigger_music_SendEntity(entity this, entity to, float sf)
                WriteByte(MSG_ENTITY, this.fade_rate * 16.0);
                WriteString(MSG_ENTITY, this.noise);
        }
-       return 1;
+       if(sendflags & SF_TRIGGER_UPDATE)
+       {
+               WriteByte(MSG_ENTITY, this.active);
+       }
+       return true;
 }
 void trigger_music_reset(entity this)
 {
-       this.cnt = !(this.spawnflags & 1);
-       this.SendFlags |= 0x80;
-}
-void trigger_music_use(entity this, entity actor, entity trigger)
-{
-       this.cnt = !this.cnt;
-       this.SendFlags |= 0x80;
+       if(this.spawnflags & START_DISABLED)
+       {
+               this.setactive(this, ACTIVE_NOT);
+       }
+       else
+       {
+               this.setactive(this, ACTIVE_ACTIVE);
+       }
 }
+
 spawnfunc(trigger_music)
 {
-       if(this.model != "") _setmodel(this, this.model);
-       if(!this.volume) this.volume = 1;
+       if(this.model != "")
+       {
+               _setmodel(this, this.model);
+       }
+       if(!this.volume)
+       {
+               this.volume = 1;
+       }
        if(!this.modelindex)
        {
                setorigin(this, this.origin + this.mins);
                setsize(this, '0 0 0', this.maxs - this.mins);
        }
-       trigger_music_reset(this);
 
-       this.use = trigger_music_use;
+       this.setactive = generic_netlinked_setactive;
+       this.use = generic_netlinked_legacy_use; // backwards compatibility
        this.reset = trigger_music_reset;
+       this.reset(this);
 
        Net_LinkEntity(this, false, 0, trigger_music_SendEntity);
 }
@@ -163,8 +179,14 @@ void TargetMusic_Advance()
 {
        // run AFTER all the thinks!
        entity best = music_default;
-       if (music_target && time < music_target.lifetime) best = music_target;
-       if (music_trigger) best = music_trigger;
+       if (music_target && time < music_target.lifetime)
+       {
+               best = music_target;
+       }
+       if (music_trigger)
+       {
+               best = music_trigger;
+       }
        LL_EACH(TargetMusic_list, it.noise, {
                const float vol0 = (getsoundtime(it, CH_BGM_SINGLE) >= 0) ? it.lastvol : -1;
                if (it == best)
@@ -181,9 +203,9 @@ void TargetMusic_Advance()
                if (vol != vol0)
                {
                        if(vol0 < 0)
-                               _sound(it, CH_BGM_SINGLE, it.noise, vol, ATTEN_NONE); // restart
+                               sound7(it, CH_BGM_SINGLE, it.noise, vol, ATTEN_NONE, 0, BIT(4)); // restart
                        else
-                               _sound(it, CH_BGM_SINGLE, "", vol, ATTEN_NONE);
+                               sound7(it, CH_BGM_SINGLE, "", vol, ATTEN_NONE, 0, BIT(4));
                        it.lastvol = vol;
                }
        });
@@ -215,16 +237,13 @@ void Net_TargetMusic()
        }
        if(e.noise != noi)
        {
-               if(e.noise)
-                       strunzone(e.noise);
-               e.noise = strzone(noi);
+               strcpy(e.noise, noi);
                precache_sound(e.noise);
                _sound(e, CH_BGM_SINGLE, e.noise, 0, ATTEN_NONE);
                if(getsoundtime(e, CH_BGM_SINGLE) < 0)
                {
                        LOG_TRACEF("Cannot initialize sound %s", e.noise);
-                       strunzone(e.noise);
-                       e.noise = string_null;
+                       strfree(e.noise);
                }
        }
        e.volume = vol;
@@ -253,28 +272,30 @@ void Net_TargetMusic()
 
 void Ent_TriggerMusic_Think(entity this)
 {
-       if(WarpZoneLib_BoxTouchesBrush(view_origin, view_origin, this, NULL))
+       if(this.active == ACTIVE_NOT)
+       {
+               return;
+       }
+       vector org = (csqcplayer) ? csqcplayer.origin : view_origin;
+       if(WarpZoneLib_BoxTouchesBrush(org + STAT(PL_MIN), org + STAT(PL_MAX), this, NULL))
        {
                music_trigger = this;
        }
-       this.nextthink = time;
 }
 
 void Ent_TriggerMusic_Remove(entity this)
 {
-       if(this.noise)
-               strunzone(this.noise);
-       this.noise = string_null;
+    strfree(this.noise);
 }
 
 NET_HANDLE(ENT_CLIENT_TRIGGER_MUSIC, bool isnew)
 {
-       int f = ReadByte();
-       if(f & 4)
+       int sendflags = ReadByte();
+       if(sendflags & SF_MUSIC_ORIGIN)
        {
                this.origin = ReadVector();
        }
-       if(f & 1)
+       if(sendflags & SF_TRIGGER_INIT)
        {
                this.modelindex = ReadShort();
                if(this.modelindex)
@@ -292,27 +313,31 @@ NET_HANDLE(ENT_CLIENT_TRIGGER_MUSIC, bool isnew)
                this.fade_time = ReadByte() / 16.0;
                this.fade_rate = ReadByte() / 16.0;
                string s = this.noise;
-               if(this.noise)
-                       strunzone(this.noise);
-               this.noise = strzone(ReadString());
+               strcpy(this.noise, ReadString());
                if(this.noise != s)
                {
                        precache_sound(this.noise);
-                       _sound(this, CH_BGM_SINGLE, this.noise, 0, ATTEN_NONE);
+                       sound7(this, CH_BGM_SINGLE, this.noise, 0, ATTEN_NONE, 0, BIT(4));
                        if(getsoundtime(this, CH_BGM_SINGLE) < 0)
                        {
-                               LOG_TRACEF("Cannot initialize sound %s", this.noise);
-                               strunzone(this.noise);
-                               this.noise = string_null;
+                               LOG_WARNF("Cannot initialize sound %s", this.noise);
+                               strfree(this.noise);
                        }
                }
        }
+       if(sendflags & SF_TRIGGER_UPDATE)
+       {
+               this.active = ReadByte();
+       }
 
        setorigin(this, this.origin);
        setsize(this, this.mins, this.maxs);
-       this.cnt = 1;
-       setthink(this, Ent_TriggerMusic_Think);
-       this.nextthink = time;
+       this.draw = Ent_TriggerMusic_Think;
+       if(isnew)
+       {
+               LL_PUSH(TargetMusic_list, this);
+               IL_PUSH(g_drawables, this);
+       }
        return true;
 }
 
index 80b3684a4e9a768b8ef17e4ea596f463d9cc886d..ccf3f674e6f069394ec256b6a086df3eb1076aee 100644 (file)
@@ -2,6 +2,8 @@
 
 .float lifetime;
 
+const int SF_MUSIC_ORIGIN = BIT(2);
+
 #ifdef CSQC
 float music_disabled;
 entity music_default;
@@ -10,8 +12,8 @@ entity music_trigger;
 // FIXME also control bgmvolume here, to not require a target_music for the default track.
 
 entityclass(TargetMusic);
-class(TargetMusic) .int state;
-class(TargetMusic) .float lastvol;
+classfield(TargetMusic) .int state;
+classfield(TargetMusic) .float lastvol;
 
 void TargetMusic_Advance();
 
index 1464da95511260b8ce4592e705b50bf9a62e7c2d..9c999ed4df4758612b9052a34aeb22101b85b905 100644 (file)
@@ -12,8 +12,7 @@
 // "classname" "target_spawn"
 // "message" "fieldname value fieldname value ..."
 // "spawnflags"
-//   1 = call the spawn function
-//   2 = trigger on map load
+//   ON_MAPLOAD = trigger on map load
 
 float target_spawn_initialized;
 .void(entity this) target_spawn_spawnfunc;
@@ -298,7 +297,7 @@ void target_spawn_use(entity this, entity actor, entity trigger)
 void target_spawn_spawnfirst(entity this)
 {
        entity act = this.target_spawn_activator;
-       if(this.spawnflags & 2)
+       if(this.spawnflags & ON_MAPLOAD)
                target_spawn_use(this, act, NULL);
 }
 
index af327b443bc21febb1c8494829bfd10e1fb4543a..11c9ad7baef1d7c682feae42db5fa9162325532a 100644 (file)
@@ -54,7 +54,7 @@ void target_speaker_use_on(entity this, entity actor, entity trigger)
        else
                snd = this.noise;
        _sound(this, CH_TRIGGER_SINGLE, snd, VOL_BASE * this.volume, this.atten);
-       if(this.spawnflags & 3)
+       if(this.spawnflags & (SPEAKER_LOOPED_ON + SPEAKER_LOOPED_OFF))
                this.use = target_speaker_use_off;
 }
 void target_speaker_use_off(entity this, entity actor, entity trigger)
@@ -64,12 +64,12 @@ void target_speaker_use_off(entity this, entity actor, entity trigger)
 }
 void target_speaker_reset(entity this)
 {
-       if(this.spawnflags & 1) // LOOPED_ON
+       if(this.spawnflags & SPEAKER_LOOPED_ON)
        {
                if(this.use == target_speaker_use_on)
                        target_speaker_use_on(this, NULL, NULL);
        }
-       else if(this.spawnflags & 2)
+       else if(this.spawnflags & SPEAKER_LOOPED_OFF)
        {
                if(this.use == target_speaker_use_off)
                        target_speaker_use_off(this, NULL, NULL);
@@ -83,7 +83,13 @@ spawnfunc(target_speaker)
        if(this.noise)
                precache_sound (this.noise);
 
-       if(!this.atten && !(this.spawnflags & 4))
+       if(!this.atten && (this.spawnflags & SPEAKER_GLOBAL))
+       {
+               LOG_WARN("target_speaker uses legacy spawnflag GLOBAL (BIT(2)), please set atten to -1 instead");
+               this.atten = -1;
+       }
+
+       if(!this.atten)
        {
                IFTARGETED
                        this.atten = ATTEN_NORM;
@@ -98,14 +104,14 @@ spawnfunc(target_speaker)
 
        IFTARGETED
        {
-               if(this.spawnflags & 8) // ACTIVATOR
+               if(this.spawnflags & SPEAKER_ACTIVATOR)
                        this.use = target_speaker_use_activator;
-               else if(this.spawnflags & 1) // LOOPED_ON
+               else if(this.spawnflags & SPEAKER_LOOPED_ON)
                {
                        target_speaker_use_on(this, NULL, NULL);
                        this.reset = target_speaker_reset;
                }
-               else if(this.spawnflags & 2) // LOOPED_OFF
+               else if(this.spawnflags & SPEAKER_LOOPED_OFF)
                {
                        this.use = target_speaker_use_on;
                        this.reset = target_speaker_reset;
@@ -113,12 +119,12 @@ spawnfunc(target_speaker)
                else
                        this.use = target_speaker_use_on;
        }
-       else if(this.spawnflags & 1) // LOOPED_ON
+       else if(this.spawnflags & SPEAKER_LOOPED_ON)
        {
                ambientsound (this.origin, this.noise, VOL_BASE * this.volume, this.atten);
                delete(this);
        }
-       else if(this.spawnflags & 2) // LOOPED_OFF
+       else if(this.spawnflags & SPEAKER_LOOPED_OFF)
        {
                objerror(this, "This sound entity can never be activated");
        }
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..53e0194be46b2e38509ab33eed11541c310feed2 100644 (file)
@@ -1 +1,7 @@
 #pragma once
+
+
+const int SPEAKER_LOOPED_ON = BIT(0);
+const int SPEAKER_LOOPED_OFF = BIT(1);
+const int SPEAKER_GLOBAL = BIT(2); // legacy, set speaker atten to -1 instead
+const int SPEAKER_ACTIVATOR = BIT(3);
index 6f5b2b595d8c09a110839cb4aeb3ca3a3ef11f42..68c5114f4d5bbf06d398f27b32584551737e42a8 100644 (file)
@@ -1,21 +1,23 @@
 #pragma once
+#include "defs.qh"
 
 IntrusiveList g_teleporters;
 STATIC_INIT(g_teleporters) { g_teleporters = IL_NEW(); }
 
 .entity pusher;
-const float TELEPORT_FLAG_SOUND = 1;
-const float TELEPORT_FLAG_PARTICLES = 2;
-const float TELEPORT_FLAG_TDEATH = 4;
-const float TELEPORT_FLAG_FORCE_TDEATH = 8;
+
+const int TELEPORT_FLAG_SOUND = BIT(0);
+const int TELEPORT_FLAG_PARTICLES = BIT(1);
+const int TELEPORT_FLAG_TDEATH = BIT(2);
+const int TELEPORT_FLAG_FORCE_TDEATH = BIT(3);
 
 #define TELEPORT_FLAGS_WARPZONE   0
 #define TELEPORT_FLAGS_PORTAL     (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH | TELEPORT_FLAG_FORCE_TDEATH)
 #define TELEPORT_FLAGS_TELEPORTER (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH)
 
 // types for .teleportable entity setting
-const float TELEPORT_NORMAL = 1; // play sounds/effects etc
-const float TELEPORT_SIMPLE = 2; // only do teleport, nothing special
+const int TELEPORT_NORMAL = 1; // play sounds/effects etc
+const int TELEPORT_SIMPLE = 2; // only do teleport, nothing special
 
 entity Simple_TeleportPlayer(entity teleporter, entity player);
 
index 87c046b0dba724fc877ad318b9b95e1be69fb8e1..4c89c4c27ed20efc86f73a678c615d68aa82673b 100644 (file)
@@ -8,7 +8,7 @@ void counter_use(entity this, entity actor, entity trigger)
        if (this.count < 0)
                return;
 
-       bool doactivate = (this.spawnflags & 4);
+       bool doactivate = (this.spawnflags & COUNTER_FIRE_AT_COUNT);
 
        if (this.count == 0)
        {
@@ -45,14 +45,15 @@ void counter_reset(entity this)
        this.count = this.cnt;
 }
 
-/*QUAKED spawnfunc_trigger_counter (.5 .5 .5) ? nomessage
+/*QUAKED spawnfunc_trigger_counter (.5 .5 .5) ? nomessage COUNTER_FIRE_AT_COUNT
 Acts as an intermediary for an action that takes multiple inputs.
 
 If nomessage is not set, it will print "1 more.. " etc when triggered and "sequence complete" when finished.
+If COUNTER_FIRE_AT_COUNT is set, it will also fire all of its targets at countdown, making it behave like trigger_mulitple with limited shots
 
 If respawntime is set, it will re-enable itself after the time once the sequence has been completed
 
-After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
+After the counter has been triggered "count" times (default 2), it will fire all of its targets.
 */
 spawnfunc(trigger_counter)
 {
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..394d15472cdbc68f289b9476ec00311e6dd22e09 100644 (file)
@@ -1 +1,4 @@
 #pragma once
+
+
+const int COUNTER_FIRE_AT_COUNT = BIT(2);
index af212ff5a42b7449bea067a2c755d4c86374782f..141f3ea9f19e513dcad6aeaa07e304efaec9dea8 100644 (file)
@@ -12,8 +12,10 @@ void flipflop_use(entity this, entity actor, entity trigger)
 
 spawnfunc(trigger_flipflop)
 {
-    if(this.spawnflags & 1)
-        this.state = 1;
+    if(this.spawnflags & START_ENABLED)
+    {
+        this.state = true;
+    }
     this.use = flipflop_use;
     this.reset = spawnfunc_trigger_flipflop; // perfect resetter
 }
index 3ea1562f084a93e4c73b7fdb0c9a26ac64dad90e..1ac0f8768d5d355b1a4b0d8d7cea8f97935c6cf5 100644 (file)
@@ -33,29 +33,31 @@ void trigger_gravity_check_think(entity this)
        }
 }
 
+// legacy
 void trigger_gravity_use(entity this, entity actor, entity trigger)
 {
-       this.state = !this.state;
+       this.setactive(this, ACTIVE_TOGGLE);
 }
 
 void trigger_gravity_touch(entity this, entity toucher)
 {
        float g;
 
-       if(this.state != true)
+       if(this.active == ACTIVE_NOT)
                return;
 
        EXACTTRIGGER_TOUCH(this, toucher);
 
        g = this.gravity;
 
-       if (!(this.spawnflags & 1))
+       if (!(this.spawnflags & GRAVITY_STICKY))
        {
                if(toucher.trigger_gravity_check)
                {
                        if(this == toucher.trigger_gravity_check.enemy)
                        {
                                // same?
+                               // NOTE: see explanation in trigger_gravity_check_think
                                toucher.trigger_gravity_check.count = 2; // gravity one more frame...
                                return;
                        }
@@ -96,12 +98,14 @@ spawnfunc(trigger_gravity)
        if(this.noise != "")
                precache_sound(this.noise);
 
-       this.state = true;
+       this.active = ACTIVE_ACTIVE;
+       this.setactive = generic_setactive;
        IFTARGETED
        {
+               // legacy use
                this.use = trigger_gravity_use;
-               if(this.spawnflags & 2)
-                       this.state = false;
+               if(this.spawnflags & GRAVITY_START_DISABLED)
+                       this.active = ACTIVE_NOT;
        }
 }
 #endif
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..872f04ad9fdc98e2a9add384d504019e913d109e 100644 (file)
@@ -1 +1,5 @@
 #pragma once
+
+
+const int GRAVITY_STICKY = BIT(0); // keep gravity multiplier even after exiting the trigger_gravity
+const int GRAVITY_START_DISABLED = BIT(1);
index 0f5c69c777f65c0540a41de281622f4af56feb08..cfcd726fcdb8e02c4a8997cf1477b0556f1c54dd 100644 (file)
@@ -9,9 +9,7 @@ void trigger_heal_touch(entity this, entity toucher)
        // only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
        if (toucher.iscreature)
        {
-               if (toucher.takedamage)
-               if (!IS_DEAD(toucher))
-               if (toucher.triggerhealtime < time)
+               if (toucher.takedamage && !IS_DEAD(toucher) && toucher.triggerhealtime < time)
                {
                        bool is_trigger = this.targetname == "";
                        if(is_trigger)
@@ -19,7 +17,7 @@ void trigger_heal_touch(entity this, entity toucher)
                        if(this.delay > 0)
                                toucher.triggerhealtime = time + this.delay;
 
-                       bool playthesound = (this.spawnflags & 4);
+                       bool playthesound = (this.spawnflags & HEAL_SOUND_ALWAYS);
                        if (toucher.health < this.max_health)
                        {
                                playthesound = true;
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..8dbeea54569366ecb08d425ea9fd2337488968fd 100644 (file)
@@ -1 +1,4 @@
 #pragma once
+
+
+const int HEAL_SOUND_ALWAYS = BIT(2);
index 9c09f923bec779ba7495071a113cddcca0011aa3..966e0cfb0fe6657287ee8135c9f9411f732de18d 100644 (file)
@@ -15,7 +15,7 @@ void trigger_hurt_touch(entity this, entity toucher)
                return;
 
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (this.team != toucher.team))
+               if(((this.spawnflags & INVERT_TEAMS) == 0) == (this.team != toucher.team))
                        return;
 
        // only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
@@ -53,7 +53,7 @@ void trigger_hurt_touch(entity this, entity toucher)
 /*QUAKED spawnfunc_trigger_hurt (.5 .5 .5) ?
 Any object touching this will be hurt
 set dmg to damage amount
-defalt dmg = 5
+default dmg = 1000
 */
 .entity trigger_hurt_next;
 entity trigger_hurt_last;
@@ -80,12 +80,12 @@ spawnfunc(trigger_hurt)
        trigger_hurt_last = this;
 }
 
-float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end)
+bool tracebox_hits_trigger_hurt(vector start, vector e_min, vector e_max, vector end)
 {
        entity th;
 
        for(th = trigger_hurt_first; th; th = th.trigger_hurt_next)
-               if(tracebox_hits_box(start, mi, ma, end, th.absmin, th.absmax))
+               if(tracebox_hits_box(start, e_min, e_max, end, th.absmin, th.absmax))
                        return true;
 
        return false;
index 4be6e86bca66c6c02fcf2adbd3c7141721292647..c4e7ae287a8e9a6eda6d79532d0c06684cc38b6b 100644 (file)
@@ -1,6 +1,6 @@
 #include "impulse.qh"
 // targeted (directional) mode
-void trigger_impulse_touch1(entity this, entity toucher)
+void trigger_impulse_touch_directional(entity this, entity toucher)
 {
        entity targ;
        float pushdeltatime;
@@ -22,26 +22,26 @@ void trigger_impulse_touch1(entity this, entity toucher)
                return;
        }
 
-       str = min(this.radius, vlen(this.origin - toucher.origin));
-
-       if(this.falloff == 1)
-               str = (str / this.radius) * this.strength;
-       else if(this.falloff == 2)
-               str = (1 - (str / this.radius)) * this.strength;
-       else
-               str = this.strength;
+       // falloff is not supported because radius is always 0 in directional mode
+       str = this.strength;
 
        pushdeltatime = time - toucher.lastpushtime;
-       if (pushdeltatime > 0.15) pushdeltatime = 0;
+       if (pushdeltatime > IMPULSE_MAX_PUSHDELTATIME)
+       {
+               pushdeltatime = 0;
+       }
        toucher.lastpushtime = time;
-       if(!pushdeltatime) return;
+       if(!pushdeltatime)
+       {
+               return;
+       }
 
-       if(this.spawnflags & 64)
+       if(this.spawnflags & IMPULSE_DIRECTIONAL_SPEEDTARGET)
        {
                float addspeed = str - toucher.velocity * normalize(targ.origin - this.origin);
                if (addspeed > 0)
                {
-                       float accelspeed = min(8 * pushdeltatime * str, addspeed);
+                       float accelspeed = min(IMPULSE_DIRECTIONAL_MAX_ACCEL_FACTOR * pushdeltatime * str, addspeed);
                        toucher.velocity += accelspeed * normalize(targ.origin - this.origin);
                }
        }
@@ -56,7 +56,7 @@ void trigger_impulse_touch1(entity this, entity toucher)
 }
 
 // Directionless (accelerator/decelerator) mode
-void trigger_impulse_touch2(entity this, entity toucher)
+void trigger_impulse_touch_accel(entity this, entity toucher)
 {
        float pushdeltatime;
 
@@ -69,9 +69,15 @@ void trigger_impulse_touch2(entity this, entity toucher)
        EXACTTRIGGER_TOUCH(this, toucher);
 
        pushdeltatime = time - toucher.lastpushtime;
-       if (pushdeltatime > 0.15) pushdeltatime = 0;
+       if (pushdeltatime > IMPULSE_MAX_PUSHDELTATIME)
+       {
+               pushdeltatime = 0;
+       }
        toucher.lastpushtime = time;
-       if(!pushdeltatime) return;
+       if(!pushdeltatime)
+       {
+               return;
+       }
 
        // div0: ticrate independent, 1 = identity (not 20)
        toucher.velocity = toucher.velocity * (this.strength ** pushdeltatime);
@@ -82,7 +88,7 @@ void trigger_impulse_touch2(entity this, entity toucher)
 }
 
 // Spherical (gravity/repulsor) mode
-void trigger_impulse_touch3(entity this, entity toucher)
+void trigger_impulse_touch_radial(entity this, entity toucher)
 {
        float pushdeltatime;
        float str;
@@ -96,17 +102,23 @@ void trigger_impulse_touch3(entity this, entity toucher)
        EXACTTRIGGER_TOUCH(this, toucher);
 
        pushdeltatime = time - toucher.lastpushtime;
-       if (pushdeltatime > 0.15) pushdeltatime = 0;
+       if (pushdeltatime > IMPULSE_MAX_PUSHDELTATIME)
+       {
+               pushdeltatime = 0;
+       }
        toucher.lastpushtime = time;
-       if(!pushdeltatime) return;
+       if(!pushdeltatime)
+       {
+               return;
+       }
 
        setsize(this, '-1 -1 -1' * this.radius,'1 1 1' * this.radius);
 
        str = min(this.radius, vlen(this.origin - toucher.origin));
 
-       if(this.falloff == 1)
+       if(this.falloff == FALLOFF_LINEAR)
                str = (1 - str / this.radius) * this.strength; // 1 in the inside
-       else if(this.falloff == 2)
+       else if(this.falloff == FALLOFF_LINEAR_INV)
                str = (str / this.radius) * this.strength; // 0 in the inside
        else
                str = this.strength;
@@ -121,15 +133,16 @@ void trigger_impulse_touch3(entity this, entity toucher)
 REGISTER_NET_LINKED(ENT_CLIENT_TRIGGER_IMPULSE)
 
 /*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ?
+Force field
 -------- KEYS --------
 target : If this is set, this points to the spawnfunc_target_position to which the player will get pushed.
                 If not, this trigger acts like a damper/accelerator field.
 
-strength : This is how mutch force to add in the direction of .target each second
-                  when .target is set. If not, this is hoe mutch to slow down/accelerate
-                  someting cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble)
+strength : This is how much force to add in the direction of .target each second
+                  when .target is set. If not, this is how much to slow down/accelerate
+                  something cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble)
 
-radius   : If set, act as a spherical device rather then a liniar one.
+radius   : If set, act as a spherical device rather then a linear one.
 
 falloff : 0 = none, 1 = liniar, 2 = inverted liniar
 
@@ -142,7 +155,7 @@ bool trigger_impulse_send(entity this, entity to, int sf)
 {
        WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_IMPULSE);
 
-       WriteInt24_t(MSG_ENTITY, this.spawnflags);
+       WriteByte(MSG_ENTITY, this.spawnflags);
        WriteCoord(MSG_ENTITY, this.radius);
        WriteCoord(MSG_ENTITY, this.strength);
        WriteByte(MSG_ENTITY, this.falloff);
@@ -166,23 +179,32 @@ spawnfunc(trigger_impulse)
 
        if(this.radius)
        {
-               if(!this.strength) this.strength = 2000 * autocvar_g_triggerimpulse_radial_multiplier;
+               if(!this.strength)
+               {
+                       this.strength = IMPULSE_DEFAULT_RADIAL_STRENGTH * autocvar_g_triggerimpulse_radial_multiplier;
+               }
                setorigin(this, this.origin);
                setsize(this, '-1 -1 -1' * this.radius,'1 1 1' * this.radius);
-               settouch(this, trigger_impulse_touch3);
+               settouch(this, trigger_impulse_touch_radial);
        }
        else
        {
                if(this.target)
                {
-                       if(!this.strength) this.strength = 950 * autocvar_g_triggerimpulse_directional_multiplier;
-                       settouch(this, trigger_impulse_touch1);
+                       if(!this.strength)
+                       {
+                               this.strength = IMPULSE_DEFAULT_DIRECTIONAL_STRENGTH * autocvar_g_triggerimpulse_directional_multiplier;
+                       }
+                       settouch(this, trigger_impulse_touch_directional);
                }
                else
                {
-                       if(!this.strength) this.strength = 0.9;
+                       if(!this.strength)
+                       {
+                               this.strength = IMPULSE_DEFAULT_ACCEL_STRENGTH;
+                       }
                        this.strength = (this.strength ** autocvar_g_triggerimpulse_accel_power) * autocvar_g_triggerimpulse_accel_multiplier;
-                       settouch(this, trigger_impulse_touch2);
+                       settouch(this, trigger_impulse_touch_accel);
                }
        }
 
@@ -191,7 +213,7 @@ spawnfunc(trigger_impulse)
 #elif defined(CSQC)
 NET_HANDLE(ENT_CLIENT_TRIGGER_IMPULSE, bool isnew)
 {
-       this.spawnflags = ReadInt24_t();
+       this.spawnflags = ReadByte();
        this.radius = ReadCoord();
        this.strength = ReadCoord();
        this.falloff = ReadByte();
@@ -205,8 +227,17 @@ NET_HANDLE(ENT_CLIENT_TRIGGER_IMPULSE, bool isnew)
        this.entremove = trigger_remove_generic;
        this.move_time = time;
 
-       if (this.radius) { settouch(this, trigger_impulse_touch3); }
-       else if (this.target) { settouch(this, trigger_impulse_touch1); }
-       else { settouch(this, trigger_impulse_touch2); }
+       if (this.radius)
+       {
+               settouch(this, trigger_impulse_touch_radial);
+       }
+       else if (this.target)
+       {
+               settouch(this, trigger_impulse_touch_directional);
+       }
+       else
+       {
+               settouch(this, trigger_impulse_touch_accel);
+       }
 }
 #endif
index a6961f5d2e7693920f56dac39df1d78011b88f91..e86de4a4970c58bb75435e570bd73afaef1128eb 100644 (file)
@@ -2,6 +2,20 @@
 
 // tZorks trigger impulse / gravity
 .float radius;
-.float falloff;
+.int falloff;
 .float strength;
 .float lastpushtime;
+
+const int FALLOFF_NO = 0;
+const int FALLOFF_LINEAR = 1;
+const int FALLOFF_LINEAR_INV = 2;
+
+const int IMPULSE_DIRECTIONAL_SPEEDTARGET = BIT(6);
+
+const float IMPULSE_DEFAULT_RADIAL_STRENGTH = 2000;
+const float IMPULSE_DEFAULT_DIRECTIONAL_STRENGTH = 950;
+const float IMPULSE_DEFAULT_ACCEL_STRENGTH = 0.9;
+
+const float IMPULSE_MAX_PUSHDELTATIME = 0.15;
+
+const float IMPULSE_DIRECTIONAL_MAX_ACCEL_FACTOR = 8;
index fde6e1fb9d6cf58e091ead371e1705dab06fbf49..3c5019a5c38b71a1ddddf0433e4c30c3327e9239 100644 (file)
@@ -1,7 +1,6 @@
 #include "jumppads.qh"
 // TODO: split target_push and put it in the target folder
 #ifdef SVQC
-#include "jumppads.qh"
 #include <common/physics/movetypes/movetypes.qh>
 
 void trigger_push_use(entity this, entity actor, entity trigger)
@@ -9,7 +8,7 @@ void trigger_push_use(entity this, entity actor, entity trigger)
        if(teamplay)
        {
                this.team = actor.team;
-               this.SendFlags |= 2;
+               this.SendFlags |= SF_TRIGGER_UPDATE;
        }
 }
 #endif
@@ -254,7 +253,7 @@ void trigger_push_touch(entity this, entity toucher)
                return;
 
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, toucher)))
+               if(((this.spawnflags & INVERT_TEAMS) == 0) == (DIFF_TEAM(this, toucher)))
                        return;
 
        EXACTTRIGGER_TOUCH(this, toucher);
@@ -317,7 +316,7 @@ bool trigger_push_test(entity this, entity item)
 {
        // first calculate a typical start point for the jump
        vector org = (this.absmin + this.absmax) * 0.5;
-       org.z = this.absmax.z - PL_MIN_CONST.z - 10;
+       org.z = this.absmax.z - PL_MIN_CONST.z - 7;
 
        if (this.target)
        {
@@ -481,7 +480,7 @@ float trigger_push_send(entity this, entity to, float sf)
 
 void trigger_push_updatelink(entity this)
 {
-       this.SendFlags |= 1;
+       this.SendFlags |= SF_TRIGGER_INIT;
 }
 
 void trigger_push_link(entity this)
@@ -577,16 +576,30 @@ void target_push_init2(entity this)
        target_push_init(this); // normal push target behaviour can be combined with a legacy pusher?
 }
 
-spawnfunc(target_push) { target_push_init2(this); }
-spawnfunc(info_notnull) { target_push_init(this); }
-spawnfunc(target_position) { target_push_init(this); }
+spawnfunc(target_push)
+{
+       target_push_init2(this);
+}
+
+spawnfunc(info_notnull)
+{
+       target_push_init(this);
+}
+spawnfunc(target_position)
+{
+       target_push_init(this);
+}
 
 #elif defined(CSQC)
 
 NET_HANDLE(ENT_CLIENT_TRIGGER_PUSH, bool isnew)
 {
        this.classname = "jumppad";
-       int mytm = ReadByte(); if(mytm) { this.team = mytm - 1; }
+       int mytm = ReadByte();
+       if(mytm)
+       {
+               this.team = mytm - 1;
+       }
        this.spawnflags = ReadInt24_t();
        this.active = ReadByte();
        this.height = ReadCoord();
@@ -606,13 +619,8 @@ NET_HANDLE(ENT_CLIENT_TRIGGER_PUSH, bool isnew)
 
 void target_push_remove(entity this)
 {
-       //if(this.classname)
-               //strunzone(this.classname);
-       //this.classname = string_null;
-
-       if(this.targetname)
-               strunzone(this.targetname);
-       this.targetname = string_null;
+       // strfree(this.classname);
+       strfree(this.targetname);
 }
 
 NET_HANDLE(ENT_CLIENT_TARGET_PUSH, bool isnew)
index 50ed0a343c8c86b7cc53e12274ddac7261bead75..07ab441fe5efcf7d61d2fe1c227c97440174b237 100644 (file)
@@ -1,11 +1,12 @@
 #pragma once
 
+
+const int PUSH_ONCE = BIT(0); // legacy, deactivate with relay instead
+const int PUSH_SILENT = BIT(1); // not used?
+
 IntrusiveList g_jumppads;
 STATIC_INIT(g_jumppads) { g_jumppads = IL_NEW(); }
 
-const float PUSH_ONCE          = 1;
-const float PUSH_SILENT                = 2;
-
 .float pushltime;
 .float istypefrag;
 .float height;
index bf20d1e9732e4dfe133ed4fc5473ae50b5021bd9..67db14421662c2d0c40483b328ee3dd30ee6babe 100644 (file)
@@ -164,23 +164,12 @@ spawnfunc(trigger_keylock)
 #elif defined(CSQC)
 void keylock_remove(entity this)
 {
-       if(this.target) { strunzone(this.target); }
-       this.target = string_null;
-
-       if(this.target2) { strunzone(this.target2); }
-       this.target2 = string_null;
-
-       if(this.target3) { strunzone(this.target3); }
-       this.target3 = string_null;
-
-       if(this.target4) { strunzone(this.target4); }
-       this.target4 = string_null;
-
-       if(this.killtarget) { strunzone(this.killtarget); }
-       this.killtarget = string_null;
-
-       if(this.targetname) { strunzone(this.targetname); }
-       this.targetname = string_null;
+       strfree(this.target);
+       strfree(this.target2);
+       strfree(this.target3);
+       strfree(this.target4);
+       strfree(this.killtarget);
+       strfree(this.targetname);
 }
 
 NET_HANDLE(ENT_CLIENT_KEYLOCK, bool isnew)
index 354ed1bfedd61f284ad76ae0f0fa73107b34abda..16118cb9d6e54906ea35f5634d095ad879f2a96f 100644 (file)
@@ -11,7 +11,7 @@ string trigger_magicear_processmessage(entity ear, entity source, float teamsay,
        magicear_matched = false;
 
        dotrigger = ((IS_PLAYER(source)) && (!IS_DEAD(source)) && ((ear.radius == 0) || (vdist(source.origin - ear.origin, <=, ear.radius))));
-       domatch = ((ear.spawnflags & 32) || dotrigger);
+       domatch = ((ear.spawnflags & MAGICEAR_REPLACE_OUTSIDE) || dotrigger);
 
        if (!domatch)
                return msgin;
@@ -19,13 +19,13 @@ string trigger_magicear_processmessage(entity ear, entity source, float teamsay,
        if (!msgin)
        {
                // we are in TUBA mode!
-               if (!(ear.spawnflags & 256))
+               if (!(ear.spawnflags & MAGICEAR_TUBA))
                        return msgin;
 
                for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                {
                        .entity weaponentity = weaponentities[slot];
-                       if(!W_Tuba_HasPlayed(source, weaponentity, ear.message, ear.movedir_x, !(ear.spawnflags & 512), ear.movedir_y, ear.movedir_z))
+                       if(!W_Tuba_HasPlayed(source, weaponentity, ear.message, ear.movedir_x, !(ear.spawnflags & MAGICEAR_TUBA_EXACTPITCH), ear.movedir_y, ear.movedir_z))
                                return msgin;
                }
 
@@ -45,31 +45,31 @@ string trigger_magicear_processmessage(entity ear, entity source, float teamsay,
                return msgin;
        }
 
-       if(ear.spawnflags & 256) // ENOTUBA
+       if(ear.spawnflags & MAGICEAR_TUBA) // ENOTUBA
                return msgin;
 
        if(privatesay)
        {
-               if(ear.spawnflags & 4)
+               if(ear.spawnflags & MAGICEAR_IGNORE_TELL)
                        return msgin;
        }
        else
        {
                if(!teamsay)
-                       if(ear.spawnflags & 1)
+                       if(ear.spawnflags & MAGICEAR_IGNORE_SAY)
                                return msgin;
                if(teamsay > 0)
-                       if(ear.spawnflags & 2)
+                       if(ear.spawnflags & MAGICEAR_IGNORE_TEAMSAY)
                                return msgin;
                if(teamsay < 0)
-                       if(ear.spawnflags & 8)
+                       if(ear.spawnflags & MAGICEAR_IGNORE_INVALIDTELL)
                                return msgin;
        }
 
        matchstart = -1;
        l = strlen(ear.message);
 
-       if(ear.spawnflags & 128)
+       if(ear.spawnflags & MAGICEAR_NODECOLORIZE)
                msg = msgin;
        else
                msg = strdecolorize(msgin);
@@ -126,7 +126,7 @@ string trigger_magicear_processmessage(entity ear, entity source, float teamsay,
                ear.message = savemessage;
        }
 
-       if(ear.spawnflags & 16)
+       if(ear.spawnflags & MAGICEAR_REPLACE_WHOLE_MESSAGE)
        {
                return ear.netname;
        }
@@ -153,7 +153,7 @@ string trigger_magicear_processmessage_forallears(entity source, float teamsay,
        for(ear = magicears; ear; ear = ear.enemy)
        {
                msgout = trigger_magicear_processmessage(ear, source, teamsay, privatesay, msgin);
-               if(!(ear.spawnflags & 64))
+               if(!(ear.spawnflags & MAGICEAR_CONTINUE))
                if(magicear_matched)
                        return msgout;
                msgin = msgout;
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..4e705868c3f094881d7175196380b4579f46b092 100644 (file)
@@ -1 +1,13 @@
 #pragma once
+
+
+const int MAGICEAR_IGNORE_SAY = BIT(0);
+const int MAGICEAR_IGNORE_TEAMSAY = BIT(1);
+const int MAGICEAR_IGNORE_TELL = BIT(2);
+const int MAGICEAR_IGNORE_INVALIDTELL = BIT(3);
+const int MAGICEAR_REPLACE_WHOLE_MESSAGE = BIT(4);
+const int MAGICEAR_REPLACE_OUTSIDE = BIT(5);
+const int MAGICEAR_CONTINUE = BIT(6);
+const int MAGICEAR_NODECOLORIZE = BIT(7);
+const int MAGICEAR_TUBA = BIT(8);
+const int MAGICEAR_TUBA_EXACTPITCH = BIT(9);
index a67baca16a2f152d69877823eee144bfd076724a..0c960ba8a16444dc1d3287692de0797846dcf26c 100644 (file)
@@ -38,7 +38,7 @@ spawnfunc(trigger_monoflop)
 {
        if(!this.wait)
                this.wait = 1;
-       if(this.spawnflags & 1)
+       if(this.spawnflags & MONOFLOP_FIXED)
                this.use = monoflop_fixed_use;
        else
                this.use = monoflop_use;
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..c64dffdee86b28265f47129684adc01e0eb6e05b 100644 (file)
@@ -1 +1,4 @@
 #pragma once
+
+
+const int MONOFLOP_FIXED = BIT(0);
index 24b7d5f2acc11419f32f0340462675f9d7fa2a05..accfbe8ac47b057d745a4542cb214ae10a66acbd 100644 (file)
@@ -24,10 +24,12 @@ void multi_trigger(entity this)
                return;         // allready been triggered
        }
 
-       if(this.spawnflags & 16384)
-       if(!IS_PLAYER(this.enemy))
+       if(this.spawnflags & ONLY_PLAYERS && !IS_PLAYER(this.enemy))
+       {
                return; // only players
+       }
 
+       // TODO: restructure this so that trigger_secret is more independent
        if (this.classname == "trigger_secret")
        {
                if (!IS_PLAYER(this.enemy))
@@ -37,9 +39,11 @@ void multi_trigger(entity this)
        }
 
        if (this.noise)
+       {
                _sound (this.enemy, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
+       }
 
-// don't trigger again until reset
+       // don't trigger again until reset
        this.takedamage = DAMAGE_NO;
 
        SUB_UseTargets(this, this.enemy, this.goalentity);
@@ -69,15 +73,20 @@ void multi_use(entity this, entity actor, entity trigger)
 
 void multi_touch(entity this, entity toucher)
 {
-       if(!(this.spawnflags & 2))
-       if(!toucher.iscreature)
-                       return;
+       if(!(this.spawnflags & ALL_ENTITIES) && !toucher.iscreature)
+       {
+               return;
+       }
 
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (this.team != toucher.team))
+       {
+               if(((this.spawnflags & INVERT_TEAMS) == 0) == (this.team != toucher.team))
+               {
                        return;
+               }
+       }
 
-// if the trigger has an angles field, check player's facing direction
+       // if the trigger has an angles field, check player's facing direction
        if (this.movedir != '0 0 0')
        {
                makevectors (toucher.angles);
@@ -87,8 +96,12 @@ void multi_touch(entity this, entity toucher)
 
        // if the trigger has pressed keys, check that the player is pressing those keys
        if(this.pressedkeys && IS_PLAYER(toucher)) // only for players
-       if(!(CS(toucher).pressedkeys & this.pressedkeys))
-               return;
+       {
+               if(!(CS(toucher).pressedkeys & this.pressedkeys))
+               {
+                       return;
+               }
+       }
 
        EXACTTRIGGER_TOUCH(this, toucher);
 
@@ -101,11 +114,11 @@ void multi_eventdamage(entity this, entity inflictor, entity attacker, float dam
 {
        if(!this.takedamage)
                return;
-       if(this.spawnflags & DOOR_NOSPLASH)
+       if(this.spawnflags & NOSPLASH)
                if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
                        return;
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (this.team != attacker.team))
+               if(((this.spawnflags & INVERT_TEAMS) == 0) == (this.team != attacker.team))
                        return;
        this.health = this.health - damage;
        if (this.health <= 0)
index d946efe5f17cc533c2b104b52fb1dc2c2e37ba82..932fda13ca94a5984f9e4d286848430147575158 100644 (file)
@@ -43,13 +43,13 @@ void multivibrator_toggle(entity this, entity actor, entity trigger)
 
 void multivibrator_reset(entity this)
 {
-       if(!(this.spawnflags & 1))
+       if(!(this.spawnflags & START_ENABLED))
                this.nextthink = 0; // wait for a trigger event
        else
                this.nextthink = max(1, time);
 }
 
-/*QUAKED trigger_multivibrator (.5 .5 .5) (-8 -8 -8) (8 8 8) START_ON
+/*QUAKED trigger_multivibrator (.5 .5 .5) (-8 -8 -8) (8 8 8) START_ENABLED
 "Multivibrator" trigger gate... repeatedly sends trigger events. When triggered, turns on or off.
 -------- KEYS --------
 target: trigger all entities with this targetname when it goes off
@@ -58,7 +58,7 @@ phase: offset of the timing
 wait: "on" cycle time (default: 1)
 respawntime: "off" cycle time (default: same as wait)
 -------- SPAWNFLAGS --------
-START_ON: assume it is already turned on (when targeted)
+START_ENABLED: assume it is already turned on (when targeted)
 */
 spawnfunc(trigger_multivibrator)
 {
index e5d0018032de0f67c63fc4ce91c5d5eaed56314a..f99d364aec5bdb560d9c1f51f5d92b3f8e77d714 100644 (file)
@@ -19,5 +19,8 @@ spawnfunc(trigger_relay)
        this.reset = spawnfunc_trigger_relay; // this spawnfunc resets fully
 }
 
-spawnfunc(target_relay) { spawnfunc_trigger_relay(this); }
+spawnfunc(target_relay)
+{
+       spawnfunc_trigger_relay(this);
+}
 #endif
index d713a05837728245f18a604f96647b5a300d40ca..18c2a40d01d569bb48cb1ba054484d1e624c4cfc 100644 (file)
@@ -9,13 +9,7 @@ void relay_activators_use(entity this, entity actor, entity trigger)
                else
                {
                        //bprint("Not using setactive\n");
-                       if(this.cnt == ACTIVE_TOGGLE)
-                               if(trg.active == ACTIVE_ACTIVE)
-                                       trg.active = ACTIVE_NOT;
-                               else
-                                       trg.active = ACTIVE_ACTIVE;
-                       else
-                               trg.active = this.cnt;
+                       generic_setactive(trg, this.cnt);
                }
        }
 }
index 728252c70400972a4259b3f49eea02c5100027d2..9adcd666ecc7ab3e73a8416ddfd118c869adce91 100644 (file)
@@ -6,7 +6,7 @@ void trigger_relay_if_use(entity this, entity actor, entity trigger)
 
        // TODO make this generic AND faster than nextent()ing through all, if somehow possible
        n = (cvar_string(this.netname) == cvar_string(this.message));
-       if(this.spawnflags & 1)
+       if(this.spawnflags & RELAYIF_NEGATE)
                n = !n;
 
        if(n)
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..6f37aa71d9e81c59914ef76cc53d5f61a0434666 100644 (file)
@@ -1 +1,4 @@
 #pragma once
+
+
+const int RELAYIF_NEGATE = BIT(0);
index fee28df51af0842986aeed926ee23aad1744f933..bf03b1542f0f957279c80f8f81ed1dbb891c0eaa 100644 (file)
@@ -4,7 +4,7 @@ void trigger_relay_teamcheck_use(entity this, entity actor, entity trigger)
 {
        if(actor.team)
        {
-               if(this.spawnflags & 2)
+               if(this.spawnflags & RELAYTEAMCHECK_INVERT)
                {
                        if(DIFF_TEAM(actor, this))
                                SUB_UseTargets(this, actor, trigger);
@@ -17,7 +17,7 @@ void trigger_relay_teamcheck_use(entity this, entity actor, entity trigger)
        }
        else
        {
-               if(this.spawnflags & 1)
+               if(this.spawnflags & RELAYTEAMCHECK_NOTEAM)
                        SUB_UseTargets(this, actor, trigger);
        }
 }
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..602d2535624437a45b2c0d2cb3b00d6096212c79 100644 (file)
@@ -1 +1,5 @@
 #pragma once
+
+
+const int RELAYTEAMCHECK_NOTEAM = BIT(0);
+const int RELAYTEAMCHECK_INVERT = BIT(1);
index 0330ce8d8cc46b1e9065ff29065ff51f233dadfd..825dd01ddeea559ac5f52d8cbd944904f0a0f0f0 100644 (file)
@@ -36,7 +36,7 @@ bool Teleport_Active(entity this, entity player)
                return false;
 
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, player)))
+               if(((this.spawnflags & INVERT_TEAMS) == 0) == (DIFF_TEAM(this, player)))
                        return false;
 
        return true;
@@ -83,7 +83,10 @@ void target_teleport_use(entity this, entity actor, entity trigger)
 
        string s = this.target; this.target = string_null;
        SUB_UseTargets(this, player, player); // TODO: should we be using toucher for trigger too?
-       if (!this.target) this.target = s;
+       if (!this.target)
+       {
+               this.target = s;
+       }
 
        SUB_UseTargets(e, player, player);
 }
@@ -157,7 +160,11 @@ NET_HANDLE(ENT_CLIENT_TRIGGER_TELEPORT, bool isnew)
        this.classname = "trigger_teleport";
        if(isnew)
                IL_PUSH(g_teleporters, this);
-       int mytm = ReadByte(); if(mytm) { this.team = mytm - 1; }
+       int mytm = ReadByte();
+       if(mytm)
+       {
+               this.team = mytm - 1;
+       }
        this.spawnflags = ReadInt24_t();
        this.active = ReadByte();
        this.speed = ReadCoord();
index 8b985795da8b8701bb69239f52caa7629df156d9..ba5dcbe443ea4c26e955adfa68b9f997eb0f8d69 100644 (file)
@@ -154,7 +154,10 @@ spawnfunc(target_viewlocation_end)
 }
 
 // compatibility
-spawnfunc(target_viewlocation) { spawnfunc_target_viewlocation_start(this); }
+spawnfunc(target_viewlocation)
+{
+       spawnfunc_target_viewlocation_start(this);
+}
 
 #elif defined(CSQC)
 
index 69c6c821ed7f23cde5c765a3f8bb989f1c2de2c8..3c393afd37bd3fd03bed40ea4f75ca9b5e49b382 100644 (file)
@@ -1,11 +1,12 @@
 #pragma once
 
-.entity viewloc;
 
 const int VIEWLOC_NOSIDESCROLL = BIT(0); // NOTE: currently unimplemented
 const int VIEWLOC_FREEAIM = BIT(1);
 const int VIEWLOC_FREEMOVE = BIT(2);
 
+.entity viewloc;
+
 #ifdef CSQC
 .entity goalentity;
 .entity enemy;
index f7287212ade9ca721895d3357b2df4942c405c4e..9db38a10b9478a6f9b53272ed21d2dc6e7353dc4 100644 (file)
@@ -21,6 +21,63 @@ void FixSize(entity e)
 }
 
 #ifdef SVQC
+void generic_setactive(entity this, int act)
+{
+       if(act == ACTIVE_TOGGLE)
+       {
+               if(this.active == ACTIVE_ACTIVE)
+               {
+                       this.active = ACTIVE_NOT;
+               }
+               else
+               {
+                       this.active = ACTIVE_ACTIVE;
+               }
+       }
+       else
+       {
+               this.active = act;
+       }
+}
+
+void generic_netlinked_setactive(entity this, int act)
+{
+       int old_status = this.active;
+       generic_setactive(this, act);
+
+       if (this.active != old_status)
+       {
+               this.SendFlags |= SF_TRIGGER_UPDATE;
+       }
+}
+
+void generic_netlinked_reset(entity this)
+{
+       IFTARGETED
+       {
+               if(this.spawnflags & START_ENABLED)
+               {
+                       this.active = ACTIVE_ACTIVE;
+               }
+               else
+               {
+                       this.active = ACTIVE_NOT;
+               }
+       }
+       else
+       {
+               this.active = ACTIVE_ACTIVE;
+       }
+
+       this.SendFlags |= SF_TRIGGER_UPDATE;
+}
+
+// Compatibility with old maps
+void generic_netlinked_legacy_use(entity this, entity actor, entity trigger)
+{
+       LOG_WARNF("Entity %s was (de)activated by a trigger, please update map to use relays", this.targetname);
+       this.setactive(this, ACTIVE_TOGGLE);
+}
 
 bool autocvar_g_triggers_debug = true;
 
@@ -116,12 +173,12 @@ void trigger_common_read(entity this, bool withtarget)
 
        if(withtarget)
        {
-               if(this.target) { strunzone(this.target); }
-               if(this.target2) { strunzone(this.target2); }
-               if(this.target3) { strunzone(this.target3); }
-               if(this.target4) { strunzone(this.target4); }
-               if(this.targetname) { strunzone(this.targetname); }
-               if(this.killtarget) { strunzone(this.killtarget); }
+               strfree(this.target);
+               strfree(this.target2);
+               strfree(this.target3);
+               strfree(this.target4);
+               strfree(this.targetname);
+               strfree(this.killtarget);
 
                int targbits = ReadByte();
 
@@ -158,23 +215,12 @@ void trigger_common_read(entity this, bool withtarget)
 
 void trigger_remove_generic(entity this)
 {
-       if(this.target) { strunzone(this.target); }
-       this.target = string_null;
-
-       if(this.target2) { strunzone(this.target2); }
-       this.target2 = string_null;
-
-       if(this.target3) { strunzone(this.target3); }
-       this.target3 = string_null;
-
-       if(this.target4) { strunzone(this.target4); }
-       this.target4 = string_null;
-
-       if(this.targetname) { strunzone(this.targetname); }
-       this.target = string_null;
-
-       if(this.killtarget) { strunzone(this.killtarget); }
-       this.killtarget = string_null;
+       strfree(this.target);
+       strfree(this.target2);
+       strfree(this.target3);
+       strfree(this.target4);
+       strfree(this.targetname);
+       strfree(this.killtarget);
 }
 #endif
 
index 49cd7be7c252bc74cc106a436c71034bc5dd8843..bfb32696a53e16c94d7c1c3d55d8f38af1b1cb0a 100644 (file)
@@ -1,11 +1,5 @@
 #pragma once
-
-const float SF_TRIGGER_INIT = 1;
-const float SF_TRIGGER_UPDATE = 2;
-const float SF_TRIGGER_RESET = 4;
-
-const float    SPAWNFLAG_NOMESSAGE = 1;
-const float    SPAWNFLAG_NOTOUCH = 1;
+#include "defs.qh"
 
 .bool pushable;
 
@@ -28,6 +22,13 @@ void target_voicescript_next(entity pl);
 void target_voicescript_clear(entity pl);
 
 void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger);
+
+void generic_setactive(entity this, int act);
+// generic methods for netlinked entities
+void generic_netlinked_reset(entity this);
+void generic_netlinked_setactive(entity this, int act);
+// WARNING: DON'T USE, ONLY TO KEEP COMPATIBILITY BECAUSE OF SWITCH FROM .state TO .alive!!!!
+void generic_netlinked_legacy_use(entity this, entity actor, entity trigger);
 #endif
 
 .float sub_target_used;
@@ -45,10 +46,4 @@ void trigger_remove_generic(entity this);
 .float active;
 .string target;
 .string targetname;
-
-const int ACTIVE_NOT           = 0;
-const int ACTIVE_ACTIVE        = 1;
-const int ACTIVE_IDLE          = 2;
-const int ACTIVE_BUSY          = 2;
-const int ACTIVE_TOGGLE                = 3;
 #endif
index 96fa81f8eee98cdbbf72ce9761e2f5eaf2c1c717..c4e50a7e71f058be20cd74201a619a5878e20777 100644 (file)
@@ -6,7 +6,7 @@ spawnfunc(turret_plasma) { if (!turret_initialize(this, TUR_PLASMA)) delete(this
 
 METHOD(PlasmaTurret, tr_attack, void(PlasmaTurret this, entity it))
 {
-    if(g_instagib)
+    if(autocvar_g_instagib)
     {
         .entity weaponentity = weaponentities[0]; // TODO: unhardcode
         FireRailgunBullet (it, weaponentity, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * max_shot_distance, 10000000000,
index 2a6f997cf3f009f533858d9099c0fb3492e2b7c3..8d20da5b6eed40b3c9f66eddffbe3b0c780b228a 100644 (file)
@@ -6,7 +6,7 @@ spawnfunc(turret_plasma_dual) { if (!turret_initialize(this, TUR_PLASMA_DUAL)) d
 
 METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret thistur, entity it))
 {
-    if (g_instagib) {
+    if (autocvar_g_instagib) {
         .entity weaponentity = weaponentities[0]; // TODO: unhardcode
         FireRailgunBullet (it, weaponentity, it.tur_shotorg, it.tur_shotorg + it.tur_shotdir_updated * max_shot_distance, 10000000000,
                            800, 0, 0, 0, 0, DEATH_TURRET_PLASMA.m_id);
index deba86c289dc8f4966407fa6dd6f7c4f9e308ed8..35ec9b2c58f96de0ac3aba803b52641394ada62c 100644 (file)
@@ -453,14 +453,12 @@ void get_mi_min_max(float mode)
 {
        vector mi, ma;
 
-       if(mi_shortname)
-               strunzone(mi_shortname);
-       mi_shortname = mapname;
-       if(!strcasecmp(substring(mi_shortname, 0, 5), "maps/"))
-               mi_shortname = substring(mi_shortname, 5, strlen(mi_shortname) - 5);
-       if(!strcasecmp(substring(mi_shortname, strlen(mi_shortname) - 4, 4), ".bsp"))
-               mi_shortname = substring(mi_shortname, 0, strlen(mi_shortname) - 4);
-       mi_shortname = strzone(mi_shortname);
+       string s = mapname;
+       if(!strcasecmp(substring(s, 0, 5), "maps/"))
+               s = substring(s, 5, strlen(s) - 5);
+       if(!strcasecmp(substring(s, strlen(s) - 4, 4), ".bsp"))
+               s = substring(s, 0, strlen(s) - 4);
+       strcpy(mi_shortname, s);
 
 #ifdef CSQC
        mi = world.mins;
@@ -1397,8 +1395,7 @@ void execute_next_frame()
        if(to_execute_next_frame)
        {
                localcmd("\n", to_execute_next_frame, "\n");
-               strunzone(to_execute_next_frame);
-               to_execute_next_frame = string_null;
+               strfree(to_execute_next_frame);
        }
 }
 void queue_to_execute_next_frame(string s)
@@ -1406,9 +1403,8 @@ void queue_to_execute_next_frame(string s)
        if(to_execute_next_frame)
        {
                s = strcat(s, "\n", to_execute_next_frame);
-               strunzone(to_execute_next_frame);
        }
-       to_execute_next_frame = strzone(s);
+       strcpy(to_execute_next_frame, s);
 }
 
 .float FindConnectedComponent_processing;
index 8d569d04e253f798debe0b17747233432166bf92..985d2ae59ef3faabdd7fce020d09d0310ddfb3a0 100644 (file)
@@ -261,11 +261,11 @@ float autocvar_cl_grapplehook_alpha = 1;
 void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg);
 
 entityclass(Hook);
-class(Hook) .entity HookType; // ENT_CLIENT_*
-class(Hook) .vector origin;
-class(Hook) .vector velocity;
-class(Hook) .float HookSilent;
-class(Hook) .float HookRange;
+classfield(Hook) .entity HookType; // ENT_CLIENT_*
+classfield(Hook) .vector origin;
+classfield(Hook) .vector velocity;
+classfield(Hook) .float HookSilent;
+classfield(Hook) .float HookRange;
 
 string Draw_GrapplingHook_trace_callback_tex;
 float Draw_GrapplingHook_trace_callback_rnd;
@@ -281,7 +281,7 @@ void Draw_GrapplingHook_trace_callback(vector start, vector hit, vector end)
        Draw_GrapplingHook_trace_callback_rnd += 0.25 * vlen(hit - start) / 8;
 }
 
-class(Hook) .float teleport_time;
+classfield(Hook) .float teleport_time;
 void Draw_GrapplingHook(entity this)
 {
        vector a, b, atrans;
index ffa1dd6e2dd5589e5623611655bce63a87bf4042..d932d98bd16f6d7554c32fb7f447ca9419be3c15 100644 (file)
@@ -45,9 +45,9 @@ SPAWNFUNC_WEAPON(weapon_tuba, WEP_TUBA)
 
 #ifdef CSQC
 entityclass(Tuba);
-class(Tuba) .int note;
-class(Tuba) .bool tuba_attenuate;
-class(Tuba) .float tuba_volume;
-class(Tuba) .float tuba_volume_initial;
-class(Tuba) .int tuba_instrument;
+classfield(Tuba) .int note;
+classfield(Tuba) .bool tuba_attenuate;
+classfield(Tuba) .float tuba_volume;
+classfield(Tuba) .float tuba_volume_initial;
+classfield(Tuba) .int tuba_instrument;
 #endif
index e46745c2acf4e971e0f0bcfa41a036d9381bfd04..c3baa12127b6c3b39a947aa8fec40524362a1443 100644 (file)
@@ -144,7 +144,7 @@ void W_Vaporizer_Attack(Weapon thiswep, entity actor, .entity weaponentity)
        if(!(trace_dphitq3surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NOIMPACT)))
                W_RocketMinsta_Explosion(actor, weaponentity, trace_endpos);
 
-       W_DecreaseAmmo(thiswep, actor, ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)), weaponentity);
+       W_DecreaseAmmo(thiswep, actor, ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)), weaponentity);
 }
 
 void W_RocketMinsta_Laser_Explode (entity this, entity directhitentity)
@@ -288,7 +288,7 @@ METHOD(Vaporizer, wr_aim, void(entity thiswep, entity actor, .entity weaponentit
 }
 METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
 {
-    float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
+    float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
     // if the laser uses load, we also consider its ammo for reloading
     if(WEP_CVAR(vaporizer, reload_ammo) && WEP_CVAR_SEC(vaporizer, ammo) && actor.(weaponentity).clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) { // forced reload
         thiswep.wr_reload(thiswep, actor, weaponentity);
@@ -349,7 +349,7 @@ METHOD(Vaporizer, wr_setup, void(entity thiswep, entity actor, .entity weaponent
 }
 METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
 {
-    float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
+    float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
     float ammo_amount = GetResourceAmount(actor, thiswep.ammo_type) >= vaporizer_ammo;
     ammo_amount += actor.(weaponentity).(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo;
     return ammo_amount;
@@ -368,7 +368,7 @@ METHOD(Vaporizer, wr_resetplayer, void(entity thiswep, entity actor))
 }
 METHOD(Vaporizer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
 {
-    float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
+    float vaporizer_ammo = ((autocvar_g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
     float used_ammo;
     if(WEP_CVAR_SEC(vaporizer, ammo))
         used_ammo = min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo));
index c8b459962eb0102247c4f308459d680e2965cf76..8896b5a442ba42d78c4420ee3c0332dacb2956c6 100644 (file)
@@ -43,7 +43,7 @@ void sys_phys_update(entity this, float dt)
        float maxspeed_mod = (!this.in_swamp) ? 1 : this.swamp_slowdown;  // cvar("g_balance_swamp_moverate");
 
 // conveyors: first fix velocity
-       if (this.conveyor.state) { this.velocity -= this.conveyor.movedir; }
+       if (this.conveyor.active) { this.velocity -= this.conveyor.movedir; }
        MUTATOR_CALLHOOK(PlayerPhysics, this, dt);
 
        if (!IS_PLAYER(this)) {
@@ -156,7 +156,7 @@ void sys_phys_update(entity this, float dt)
        LABEL(end)
        if (IS_ONGROUND(this)) { this.lastground = time; }
 // conveyors: then break velocity again
-       if (this.conveyor.state) { this.velocity += this.conveyor.movedir; }
+       if (this.conveyor.active) { this.velocity += this.conveyor.movedir; }
        this.lastflags = this.flags;
 
        this.lastclassname = this.classname;
index 5ae47c394da75d90665680af45cb8fccbfa9f71a..c3594c0136cfff9cfca75c0573cbfd1349ed2d8e 100644 (file)
@@ -4,6 +4,7 @@ void sys_phys_fix(entity this, float dt)
 {
        WarpZone_PlayerPhysics_FixVAngle(this);
        Physics_UpdateStats(this);
+       PM_ClientMovement_UpdateStatus(this);
 }
 
 bool sys_phys_override(entity this, float dt)
index d44c5e89cdda2acacbd1b615bfbc55dc8bb93b9f..addced2b3f0a5d6aa7932f9cc224ed5843047bfd 100644 (file)
        #define bool float
 #endif
 
+#ifndef QCC_SUPPORT_ACCUMULATE
+       #warning "QCC does not support accumulate, may not compile correctly"
+       #define ACCUMULATE
+#else
+       #define ACCUMULATE [[accumulate]]
+#endif
+
 #ifndef QCC_SUPPORT_ERASEABLE
        #define ERASEABLE
 #else
        #define ERASEABLE [[eraseable]]
 #endif
 
+#ifndef QCC_SUPPORT_ALIAS
+    #warning "QCC does not support alias, may not compile correctly"
+    #define ALIAS(var)
+#else
+    #define ALIAS(var) [[alias(var)]]
+#endif
+
 #include <dpdefs/pre.qh>
 
 #if defined(CSQC)
 
 #include <dpdefs/post.qh>
 
+#ifndef QCC_SUPPORT_POW
+    #define pow(a, b) pow(a, b)
+#else
+    #define pow(a, b) ((a) ** (b))
+#endif
+
 #include "self.qh"
 
 #define USING(name, T) typedef T name
index c265325f8f6c75d20de492fcf1c81211195e5849..2d1e40212fba3c9cd2d9f28216a5a3c2071c3d7e 100644 (file)
@@ -2,7 +2,7 @@
 
 #ifdef QCC_SUPPORT_ACCUMULATE
        #define ACCUMULATE_FUNCTION(func, otherfunc) \
-               [[accumulate]] void func() \
+               ACCUMULATE void func() \
                { \
                        otherfunc(); \
                }
index d1bdc4fe5b55e609bc4d02b32dc0f55b0761f21a..5ca0ed56525ee33886c46a0a7c27ecfd7763068b 100644 (file)
        #endif
 #endif
 
+#ifndef QCC_SUPPORT_ALIAS
+       #ifdef GMQCC
+               #define QCC_SUPPORT_ALIAS
+       #endif
+#endif
+
+#ifndef QCC_SUPPORT_POW
+    #ifdef GMQCC
+        #define QCC_SUPPORT_POW
+    #endif
+#endif
+
 #ifdef GMQCC
     #define LABEL(id) :id
 #else
index a17f2bad72397d55a470fc32bb64851cfcbe5152..e8e2c54880a1a29eed6c48d50a6ac0cd44c016ff 100644 (file)
@@ -87,7 +87,7 @@ const noref vector default_vector = '0 0 0';
 //  e.g.: AUTOCVAR(mycvar, float, 2.5, "cvar description")
 
 #define __AUTOCVAR(file, archive, var, type, desc, default) \
-       [[accumulate]] void RegisterCvars(void(string, string, string, bool, string) f) \
+       ACCUMULATE void RegisterCvars(void(string, string, string, bool, string) f) \
        { \
                f( #var, repr_cvar_##type(default), desc, archive, file); \
        } \
index 4f34bb4853ade7f0149274ebdb3c325d4468147a..5d6473080a60d9b470856efb27fc1344056764c3 100644 (file)
@@ -6,8 +6,8 @@
        #include "self.qh"
 
        entityclass(Defer);
-       class(Defer).entity owner;
-       class(Defer).void(entity) defer_func;
+       classfield(Defer).entity owner;
+       classfield(Defer).void(entity) defer_func;
 
        /** Remove entity */
        void SUB_Remove(entity this)
index 449aa373b31885d5aa3a5958d7855c94c4fd3d6c..1b58eb1b9fcf75d0ddd7196843a6cb5be402d695 100644 (file)
@@ -5,12 +5,10 @@
 GENERIC_COMMAND(mx, "Send a matrix command") {
     switch (argv(1)) {
         case "user":
-            if (matrix_user) strunzone(matrix_user);
-            matrix_user = strzone(substring(command, argv_start_index(2), -1));
+            strcpy(matrix_user, substring(command, argv_start_index(2), -1));
             break;
         case "token":
-            if (matrix_access_token) strunzone(matrix_access_token);
-            matrix_access_token = strzone(substring(command, argv_start_index(2), -1));
+            strcpy(matrix_access_token, substring(command, argv_start_index(2), -1));
             break;
         case "messages":
             MX_Messages(string_null);
index c399c2aa6cf86e2d9a9ba910667c8cd1c926ba43..57754d04e4334d05da4a3701217d7bf6e17d7cb4 100644 (file)
@@ -204,7 +204,8 @@ void MX_Say_(entity fh, entity pass, int status)
             fh.url_verb = "PUT";
             fh.url_content_type = "application/json";
             url_fputs(fh, sprintf("{\"msgtype\": \"m.text\", \"body\": \"%s\"}", pass.message));
-            strunzone(pass.message); delete(pass);
+            strfree(pass.message);
+            delete(pass);
             url_fclose(fh);
             break;
         }
index 6c29a4b88dd100f74ded51a0fe91ad82179c7d25..cbb1079244d2ef5a6806f94387a8826380dc9589 100644 (file)
 
        #include "p99.qh"
        #define OVERLOAD(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__))
-       /** for use within a macro */
+       /** for use within macros */
        #define OVERLOAD_(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__))
+       #define OVERLOAD__(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__))
 #else
        #define EVAL(...) __VA_ARGS__
 
-       #define OVERLOAD_(F, ...) F##_##__VA_COUNT__(__VA_ARGS__)
        #define OVERLOAD(F, ...) F##_##__VA_COUNT__(__VA_ARGS__)
+       #define OVERLOAD_(F, ...) F##_##__VA_COUNT__(__VA_ARGS__)
+       #define OVERLOAD__(F, ...) F##_##__VA_COUNT__(__VA_ARGS__)
 #endif
 
 #if defined(CSQC)
index fe2952e2c4025c3d5f84854627824cc3f4ab3d6f..7b3f581b38f059cd4e4252905ae0dcf243983209 100644 (file)
@@ -50,7 +50,7 @@ STATIC_INIT(RegisterTempEntities_renumber) { FOREACH(TempEntities, true, it.m_id
 
 #ifdef CSQC
        #define REGISTER_NET_LINKED(id) \
-               [[accumulate]] NET_HANDLE(id, bool isnew) \
+               ACCUMULATE NET_HANDLE(id, bool isnew) \
                { \
                        this = __self; \
                        this.sourceLoc = __FILE__ ":" STR(__LINE__); \
@@ -107,7 +107,6 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); }
 #ifdef SVQC
        const int MSG_ENTITY = 5;
 
-       .int Version;  // deprecated, use SendFlags
        .int SendFlags;
 
        IntrusiveList g_uncustomizables;
@@ -202,8 +201,7 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); }
        {
                if (g_buf == "") return;
                localcmd("\ncmd c2s \"", strreplace("$", "$$", g_buf), "\"\n");
-               strunzone(g_buf);
-               g_buf = string_null;
+               strfree(g_buf);
        }
 #endif
 
@@ -301,8 +299,7 @@ MACRO_END
                string s = string_null;
                yenc_single(b, s);
                string tmp = strcat(g_buf, s);
-               if (g_buf) strunzone(g_buf);
-               g_buf = strzone(tmp);
+               strcpy(g_buf, tmp);
        }
        void WriteShort(int to, int b)
        {
index 782798c9fe5c492799d0892f4f1f5cc3f155731d..5ef9cf8b6b17708b6bed1bb664b593d049496e53 100644 (file)
@@ -2,11 +2,11 @@
 
 // noises "usually" start in the range -1..1
 entityclass(Noise);
-class(Noise).float noise_baccum;
-class(Noise).float noise_paccum;
-class(Noise).float noise_paccum2;
-class(Noise).float noise_paccum3;
-class(Noise).float noise_bstate;
+classfield(Noise).float noise_baccum;
+classfield(Noise).float noise_paccum;
+classfield(Noise).float noise_paccum2;
+classfield(Noise).float noise_paccum3;
+classfield(Noise).float noise_bstate;
 
 ERASEABLE
 float Noise_Brown(entity e, float dt)
index bd1d34666be57589a5f8c54e4581e325c52dbe65..b22ff791501c9a990c93e5d9c7f3dabc2c35f661 100644 (file)
@@ -5,19 +5,16 @@
 #include "static.qh"
 
 .vector origin;
+
 .bool pure_data;
-/** @deprecated use new_pure or NEW(class) */
-#define make_pure(e) \
-       MACRO_BEGIN \
-       { \
-               (e).pure_data = true; \
-       } MACRO_END
-#define make_impure(e) \
-       MACRO_BEGIN \
-       { \
-               (e).pure_data = false; \
-       } MACRO_END
 #define is_pure(e) ((e).pure_data)
+/** @deprecated use new_pure or NEW(class) */
+#define make_pure(e) MACRO_BEGIN \
+       (e).pure_data = true; \
+MACRO_END
+#define make_impure(e) MACRO_BEGIN \
+       (e).pure_data = false; \
+MACRO_END
 
 .string classname;
 /** Location entity was spawned from in source */
@@ -58,11 +55,11 @@ entity __spawn(string _classname, string _sourceLoc, bool pure)
 #define entityclass_1(name) entityclass_2(name, Object)
 #ifndef QCC_SUPPORT_ENTITYCLASS
        #define entityclass_2(name, base) USING(name, entity)
-       #define class(name)
+       #define classfield(name)
        #define _new(class, pure) __spawn( #class, __FILE__ ":" STR(__LINE__), pure)
 #else
        #define entityclass_2(name, base) entityclass name : base {}
-       #define class(name) [[class(name)]]
+       #define classfield(name) [[class(name)]]
        #define _new(class, pure) ((class) __spawn( #class, __FILE__ ":" STR(__LINE__), pure))
 #endif
 /** entities you care about seeing (.origin works) */
@@ -71,12 +68,13 @@ entity __spawn(string _classname, string _sourceLoc, bool pure)
 #define new_pure(class) _new(class, true)
 #define spawn() __spawn("entity", __FILE__ ":" STR(__LINE__), false)
 
-[[accumulate]] void ONREMOVE(entity this) {}
+ACCUMULATE void ONREMOVE(entity this) {}
 
 #ifndef SVQC
        #define delete_fn builtin_remove
 #endif
 
+.void(entity this) dtor;
 #define delete(this) MACRO_BEGIN { \
     entity _this = (this); \
     void(entity) _dtor = _this.dtor; \
@@ -104,7 +102,7 @@ void clearentity(entity e)
 }
 
 // Classes have a `spawn##cname(entity)` constructor
-// The parameter is used across [[accumulate]] functions
+// The parameter is used across ACCUMULATE functions
 
 .bool transmute;
 
@@ -138,12 +136,149 @@ void clearentity(entity e)
     } \
     MACRO_END
 
-#define CONSTRUCTOR(cname, ...) \
-       cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) \
-       { \
-               return = this; \
-       } \
-       [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
+#define CLASS(...) EVAL_CLASS(OVERLOAD__(CLASS, __VA_ARGS__))
+#define EVAL_CLASS(...) __VA_ARGS__
+
+#define ATTRIB(...) EVAL_ATTRIB(OVERLOAD_(ATTRIB, __VA_ARGS__))
+#define EVAL_ATTRIB(...) __VA_ARGS__
+
+#ifdef QCC_SUPPORT_CLASS
+
+#warning "QCC_SUPPORT_CLASS not implemented"
+
+#define CLASS_1(name)                               CLASS_2(name, entity)
+#define CLASS_2(name, base)                         class name : base {
+
+#define INIT(class)                                     void class::class()
+#define CONSTRUCTOR(class, ...)                         void class::class(__VA_ARGS__)
+#define DESTRUCTOR(class)                               class::~class()
+
+#define SUPER(class)                                    super
+
+#define ATTRIB_3(class, name, T)                        T name
+#define ATTRIB_4(class, name, T, val)                   ATTRIB_3(class, name, T) = val
+#define STATIC_ATTRIB(class, name, T, val)              static T name = val
+
+#define ATTRIB_STRZONE(class, name, T, val)             T name = val
+#define STATIC_ATTRIB_STRZONE(class, name, T, val)      static T name = val
+
+#define ATTRIBARRAY(class, name, T, val)                T name[val]
+
+#define METHOD(class, name, prototype)                  virtual void class::name()
+#define STATIC_METHOD(class, name, prototype)           static void class::name()
+
+#define ENDCLASS(class)                             };
+
+#else
+
+#define CLASS_1(cname) CLASS_2(cname, )
+#define CLASS_2(cname, base)                                                                       \
+       entityclass(cname, base);                                                                      \
+       classfield(cname).bool instanceOf##cname;                                                      \
+       DEBUG_STUFF(cname)                                                                             \
+       VTBL(cname, base)                                                                              \
+       _INIT_STATIC(cname)                                                                            \
+       {                                                                                              \
+               if (cname##_vtbl && !this.transmute)                                                       \
+               {                                                                                          \
+                       copyentity(cname##_vtbl, this);                                                        \
+                       return;                                                                                \
+               }                                                                                          \
+               spawn##base##_static(this);                                                                \
+               this.instanceOf##cname = true;                                                             \
+       }                                                                                              \
+       INIT(cname)                                                                                    \
+       {                                                                                              \
+               /* Only statically initialize the current class, it contains everything it inherits */     \
+               if (cname##_vtbl.vtblname == this.classname)                                               \
+               {                                                                                          \
+                       spawn##cname##_static(this);                                                           \
+                       this.transmute = false;                                                                \
+                       this.classname = #cname;                                                               \
+                       this.vtblname = string_null;                                                           \
+                       this.vtblbase = cname##_vtbl;                                                          \
+               }                                                                                          \
+               spawn##base##_1(this);                                                                     \
+       }
+
+#define INIT(cname)                                                                                \
+       ACCUMULATE cname spawn##cname##_1(cname this)
+
+#define CONSTRUCTOR(cname, ...)                                                                    \
+       cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)                                          \
+       {                                                                                              \
+               return = this;                                                                             \
+       }                                                                                              \
+       ACCUMULATE cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
+
+#define DESTRUCTOR(cname)                                                                          \
+       STATIC_METHOD(cname, dtorimpl, void(cname this));                                              \
+    METHOD(cname, dtor, void(cname this))                                                          \
+    {                                                                                              \
+        METHOD_REFERENCE(cname, dtorimpl)(this);                                                   \
+        this.instanceOf##cname = false;                                                            \
+        entity super = SUPER(cname);                                                               \
+        if (super != cname##_vtbl) super.dtor(this);                                               \
+    }                                                                                              \
+       STATIC_METHOD(cname, dtorimpl, void(cname this))
+
+#define SUPER(cname) (cname##_vtbl.vtblbase)
+
+#define ATTRIB_3(cname, name, type) classfield(cname) .type name
+#define ATTRIB_4(cname, name, type, val)                                                           \
+       ATTRIB_3(cname, name, type);                                                                   \
+       INIT(cname)                                                                                    \
+       {                                                                                              \
+               noref bool strzone; /* Error on strzone() calls. */                                        \
+               this.name = val;                                                                           \
+       }                                                                                              \
+       ATTRIB_3(cname, name, type)
+
+#define STATIC_ATTRIB(cname, name, type, val)                                                      \
+       type cname##_##name;                                                                           \
+       _INIT_STATIC(cname)                                                                            \
+       {                                                                                              \
+               noref bool strzone; /* Error on strzone() calls. */                                        \
+               cname##_##name = val;                                                                      \
+       }
+
+// cleanup potentially zoned strings from base classes
+#define ATTRIB_STRZONE(cname, name, type, val)                                                     \
+       classfield(cname).type name;                                                                   \
+       INIT(cname)                                                                                    \
+       {                                                                                              \
+               strcpy(this.name, val);                                                                    \
+       }
+
+#define STATIC_ATTRIB_STRZONE(cname, name, type, val)                                              \
+       type cname##_##name;                                                                           \
+       _INIT_STATIC(cname)                                                                            \
+       {                                                                                              \
+               strcpy(cname##_##name, val);                                                               \
+       }
+
+#define ATTRIBARRAY(cname, name, type, cnt)                                                        \
+       classfield(cname) .type name[cnt]
+
+#define METHOD(cname, name, prototype)                                                             \
+       STATIC_METHOD(cname, name, prototype);                                                         \
+       classfield(cname) .prototype name;                                                             \
+       _INIT_STATIC(cname)                                                                            \
+       {                                                                                              \
+               this.name = METHOD_REFERENCE(cname, name);                                                 \
+       }                                                                                              \
+       STATIC_METHOD(cname, name, prototype)
+
+#define STATIC_METHOD(cname, name, prototype)                                                      \
+       prototype METHOD_REFERENCE(cname, name)
+
+#define ENDCLASS(cname)                                                                            \
+       INIT(cname)                                                                                    \
+       {                                                                                              \
+               return this;                                                                               \
+       }
+
+// impl
 
 .string vtblname;
 .entity vtblbase;
@@ -168,128 +303,25 @@ STATIC_INIT(RegisterClasses)
        } \
        ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init)
 
-#define _INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this)
-#define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this)
+#define _INIT_STATIC(cname) ACCUMULATE void spawn##cname##_static(cname this)
 
 #if NDEBUG
        #define DEBUG_STUFF(cname)
 #else
        #define DEBUG_STUFF(cname) \
-               bool is_##cname(entity e) { return e.instanceOf##cname; } \
-               void isnt_##cname(entity e) { eprint(e); }
+               ERASEABLE bool is_##cname(entity e) { return e.instanceOf##cname; } \
+               ERASEABLE void isnt_##cname(entity e) { eprint(e); }
 #endif
 
-
-#define CLASS(cname, base)                  \
-       entityclass(cname, base);               \
-       class(cname).bool instanceOf##cname;    \
-       DEBUG_STUFF(cname)                      \
-       VTBL(cname, base)                       \
-       _INIT_STATIC(cname)                     \
-       {                                       \
-               if (cname##_vtbl && !this.transmute)\
-               {                                   \
-                       copyentity(cname##_vtbl, this); \
-                       return;                         \
-               }                                   \
-               spawn##base##_static(this);         \
-               this.instanceOf##cname = true;      \
-       }                                       \
-       INIT(cname)                             \
-       {                                       \
-               /* Only statically initialize the current class, it contains everything it inherits */ \
-               if (cname##_vtbl.vtblname == this.classname) \
-               {                                   \
-                       spawn##cname##_static(this);    \
-                       this.transmute = false;         \
-                       this.classname = #cname;        \
-                       this.vtblname = string_null;    \
-                       this.vtblbase = cname##_vtbl;   \
-               }                                   \
-               spawn##base##_1(this);              \
-       }
-
 #define METHOD_REFERENCE(cname, name) \
        cname##_##name
 
-#define STATIC_METHOD(cname, name, prototype) \
-       prototype METHOD_REFERENCE(cname, name)
-
-#define METHOD(cname, name, prototype) \
-       STATIC_METHOD(cname, name, prototype); \
-       class(cname) .prototype name; \
-       _INIT_STATIC(cname) \
-       { \
-               this.name = METHOD_REFERENCE(cname, name); \
-       } \
-       STATIC_METHOD(cname, name, prototype)
-
-#define DESTRUCTOR(cname) \
-       STATIC_METHOD(cname, dtorimpl, void(cname this)); \
-    METHOD(cname, dtor, void(cname this)) \
-    { \
-        METHOD_REFERENCE(cname, dtorimpl)(this); \
-        this.instanceOf##cname = false; \
-        entity super = SUPER(cname); \
-        if (super != cname##_vtbl) super.dtor(this); \
-    } \
-       STATIC_METHOD(cname, dtorimpl, void(cname this))
-
-#define ATTRIB(...) EVAL_ATTRIB(OVERLOAD_(ATTRIB, __VA_ARGS__))
-#define EVAL_ATTRIB(...) __VA_ARGS__
-#define ATTRIB_3(cname, name, type) class(cname) .type name
-#define ATTRIB_4(cname, name, type, val) \
-       ATTRIB_3(cname, name, type); \
-       INIT(cname) \
-       { \
-               noref bool strzone; /* Error on strzone() calls. */ \
-               this.name = val; \
-       } \
-       ATTRIB_3(cname, name, type)
-
-#define STATIC_ATTRIB(cname, name, type, val) \
-       type cname##_##name; \
-       _INIT_STATIC(cname) \
-       { \
-               noref bool strzone; /* Error on strzone() calls. */ \
-               cname##_##name = val; \
-       }
-
-// cleanup potentially zoned strings from base classes
-
-#define ATTRIB_STRZONE(cname, name, type, val)      \
-       class(cname).type name;                \
-       INIT(cname) \
-       { \
-               if (this.name) \
-                       strunzone(this.name); \
-               this.name = strzone(val); \
-       }
-
-#define STATIC_ATTRIB_STRZONE(cname, name, type, val) \
-       type cname##_##name; \
-       _INIT_STATIC(cname) \
-       { \
-        if (cname##_##name) \
-            strunzone(cname##_##name); \
-               cname##_##name = val; \
-       }
-
-#define ATTRIBARRAY(cname, name, type, cnt) \
-       class(cname) .type name[cnt]
-
-#define ENDCLASS(cname) \
-       INIT(cname) \
-       { \
-               return this; \
-       }
-
-#define SUPER(cname) (cname##_vtbl.vtblbase)
+#endif
 
 #define spawn_static(this)
 #define spawn_1(this)
 #define _vtbl NULL
-CLASS(Object, );
+CLASS(Object)
     DESTRUCTOR(Object) { builtin_remove(this); }
     #define remove(this) delete(this)
        METHOD(Object, describe, string(Object this))
index 306a107d7e722bc4b6706bd447249d0588e1a694..d8f18a02c96e4ab98b749530dd5f1f58550609b5 100644 (file)
@@ -22,7 +22,7 @@
  */
 #define REGISTRY(id, max) \
        void Register##id(); \
-       [[accumulate]] void REGISTRY_DEPENDS_(id) {} \
+       ACCUMULATE void REGISTRY_DEPENDS_(id) {} \
        REGISTRY_BEGIN(id) {} \
        REGISTRY_END(id) {} \
        void _Register##id() {} \
 #define REGISTRY_DEPENDS_(id) Register##id##_Depends()
 
 /** Called before initializing a registry. */
-#define REGISTRY_BEGIN(id) [[accumulate]] void REGISTRY_BEGIN_(id) { noref void() f = Register##id; } void REGISTRY_BEGIN_(id)
+#define REGISTRY_BEGIN(id) ACCUMULATE void REGISTRY_BEGIN_(id) { noref void() f = Register##id; } void REGISTRY_BEGIN_(id)
 #define REGISTRY_BEGIN_(id) Register##id##_First()
 
 /** Called after initializing a registry. */
-#define REGISTRY_END(id) [[accumulate]] void REGISTRY_END_(id) { noref void() f = Register##id; } void REGISTRY_END_(id)
+#define REGISTRY_END(id) ACCUMULATE void REGISTRY_END_(id) { noref void() f = Register##id; } void REGISTRY_END_(id)
 #define REGISTRY_END_(id) Register##id##_Done()
 
 REGISTRY(Registries, BITS(8))
@@ -104,7 +104,7 @@ REGISTRY(Registries, BITS(8))
        REGISTRY_PUSH(registry, fld, e); \
 } MACRO_END
 
-#define REGISTER_INIT(id) [[accumulate]] void Register_##id##_init(entity this)
+#define REGISTER_INIT(id) ACCUMULATE void Register_##id##_init(entity this)
 
 /** internal next pointer */
 #define REGISTRY_NEXT enemy
@@ -147,9 +147,9 @@ REGISTRY(Registries, BITS(8))
 #define REGISTRY_HASH(id) Registry_hash_##id
 
 ERASEABLE
-[[accumulate]] void Registry_check(string r, string server) { }
+ACCUMULATE void Registry_check(string r, string server) { }
 ERASEABLE
-[[accumulate]] void Registry_send_all() { }
+ACCUMULATE void Registry_send_all() { }
 
 #ifdef SVQC
 void Registry_send(string id, string hash);
index c7a42042deac253dc3172aeaf929a80ba2958b18..656989782672e60c948199c0b8deb94f2f10b0a6 100644 (file)
        #define REPLICATE(...) EVAL_REPLICATE(OVERLOAD(REPLICATE, __VA_ARGS__))
        #define EVAL_REPLICATE(...) __VA_ARGS__
 
-       [[accumulate]] void ReplicateVars(entity this, entity store, string thisname, int i) {}
+       ACCUMULATE void ReplicateVars(entity this, entity store, string thisname, int i) {}
 
        #define REPLICATE_3(fld, type, var) REPLICATE_4(fld, type, var, )
        #define REPLICATE_4(fld, type, var, func) REPLICATE_##type(fld, var, func)
        #define REPLICATE_string(fld, var, func) \
                REPLICATE_7(fld, string, var, , \
-       { if (field) strunzone(field); field = strzone(it); }, \
-       { if (field) strunzone(field); field = string_null; }, \
+       { strcpy(field, it); }, \
+       { strfree(field); }, \
        { \
                /* also initialize to the default value of func when requesting cvars */ \
                string s = func(field); \
                if (s != field) \
                { \
-                   strunzone(field); \
-                   field = strzone(s); \
+                   strcpy(field, s); \
                } \
        })
        #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func,  { field = stof(it); },          , )
index 0a61cc003dfdc9046acf24dc7b33b057115732e8..4299c19cd3674a286d3b5eea310a0754f3db0ad1 100644 (file)
@@ -12,7 +12,7 @@
 // Step 2: const self
 #if 1
     #define self (RVALUE, self)
-    [[alias("self")]] entity __self;
+    ALIAS("self") entity __self;
     #define setself(s) (__self = s)
     #define WITHSELF(value, block) WITH(entity, __self, value, (RVALUE, block))
 #endif
index af4b47ab8058ad35a8f8b6405538cc3f4ed32a31..8c362d4305cd98721075bfe84aa8a7a1ab0c4910 100644 (file)
@@ -2,7 +2,7 @@
 
 entityclass(Sort);
 // .float(entity,entity) sort_cmp;
-class(Sort).entity chain, sort_next, sort_prev;
+classfield(Sort).entity chain, sort_next, sort_prev;
 
 entity Sort_Spawn();
 
index e14002a6d5b3812f59533e82ae5346463a610ec5..d3198b3ce4c7666bf986564916b9d9678b3dc097 100644 (file)
@@ -86,7 +86,7 @@ noref bool require_spawnfunc_prefix;
        #define spawnfunc_1(id) spawnfunc_2(id, FIELDS_UNION)
        #define spawnfunc_2(id, whitelist) \
                void __spawnfunc_##id(entity this); \
-               [[accumulate]] void spawnfunc_##id(entity this) \
+               ACCUMULATE void spawnfunc_##id(entity this) \
                { \
                    if (!__spawnfunc_first) { \
                 __spawnfunc_first = true; \
@@ -163,6 +163,7 @@ noref bool require_spawnfunc_prefix;
                FIELD_SCALAR(fld, bgmscriptsustain) \
                FIELD_SCALAR(fld, bgmscript) \
                FIELD_SCALAR(fld, button0) \
+               FIELD_SCALAR(fld, chmap) \
                FIELD_SCALAR(fld, cnt) \
                FIELD_SCALAR(fld, colormap) \
                FIELD_SCALAR(fld, count) \
@@ -182,10 +183,12 @@ noref bool require_spawnfunc_prefix;
                FIELD_SCALAR(fld, dmg_force) \
                FIELD_SCALAR(fld, dmg_radius) \
                FIELD_SCALAR(fld, effects) \
+               FIELD_SCALAR(fld, falloff) \
                FIELD_SCALAR(fld, flags) \
                FIELD_SCALAR(fld, fog) \
                FIELD_SCALAR(fld, frags) \
                FIELD_SCALAR(fld, frame) \
+               FIELD_SCALAR(fld, gametype) \
                FIELD_SCALAR(fld, gametypefilter) \
                FIELD_SCALAR(fld, geomtype) \
                FIELD_SCALAR(fld, gravity) \
@@ -216,6 +219,7 @@ noref bool require_spawnfunc_prefix;
                FIELD_SCALAR(fld, noalign) \
                FIELD_SCALAR(fld, noise1) \
                FIELD_SCALAR(fld, noise2) \
+               FIELD_SCALAR(fld, noise3) \
                FIELD_SCALAR(fld, noise) \
                FIELD_SCALAR(fld, phase) \
                FIELD_SCALAR(fld, platmovetype) \
@@ -243,6 +247,7 @@ noref bool require_spawnfunc_prefix;
                FIELD_SCALAR(fld, target_random) \
                FIELD_SCALAR(fld, target_range) \
                FIELD_SCALAR(fld, team) \
+               FIELD_SCALAR(fld, trigger_reverse) \
                FIELD_SCALAR(fld, turret_scale_health) \
                FIELD_SCALAR(fld, turret_scale_range) \
                FIELD_SCALAR(fld, turret_scale_respawn) \
@@ -256,6 +261,7 @@ noref bool require_spawnfunc_prefix;
                FIELD_VEC(fld, absmin) \
                FIELD_VEC(fld, angles) \
                FIELD_VEC(fld, avelocity) \
+               FIELD_VEC(fld, beam_color)\
                FIELD_VEC(fld, debrisavelocityjitter) \
                FIELD_VEC(fld, debrisvelocity) \
                FIELD_VEC(fld, debrisvelocityjitter) \
index 6f511fcecfa1c9c1f2ef842ad5fe47ac44fbd7ef..e0ec96b8ec0c43872992e12523329c0be74e8f5d 100644 (file)
@@ -17,7 +17,9 @@ void profile(string s)
 }
 
 #define _STATIC_INIT(func, where) \
-       [[accumulate]] void _static_##func() { profile(#func); } \
+       ACCUMULATE void _static_##func##profile() { profile(#func); } \
+       ACCUMULATE_FUNCTION(where, _static_##func##profile) \
+       ACCUMULATE void _static_##func(); \
        ACCUMULATE_FUNCTION(where, _static_##func) \
        void _static_##func()
 
index 1100c474cb9eb49074cd85d08431fd0f0ba61012..03bd34b813af0714b0380c0aa3ea423713b86bd3 100644 (file)
@@ -53,7 +53,7 @@ int g_magic_stats_hole = 0;
                                REGISTRY_RESERVE(Stats, m_id, STAT_##id, z); \
                        } \
                } \
-               [[accumulate]] void stats_get() \
+               ACCUMULATE void stats_get() \
                { \
                        T it = getstat_##T(STAT_##id.m_id); \
                        /* if (it != CAT(_STAT(id), _prev)) \
@@ -111,7 +111,7 @@ int g_magic_stats_hole = 0;
                                REGISTRY_RESERVE(Stats, m_id, STAT_##id, z); \
                        } \
                } \
-               [[accumulate]] void stats_add() \
+               ACCUMULATE void stats_add() \
                { \
                        .T fld = _STAT(id); \
                        addstat_##T(STAT_##id.m_id, fld); \
@@ -120,7 +120,7 @@ int g_magic_stats_hole = 0;
     /** TODO: do we want the global copy to update? */
     #define REGISTER_STAT_3(id, T, expr) \
        REGISTER_STAT_2(id, T); \
-       [[accumulate]] void GlobalStats_update(entity this) { STAT(id, this) = (expr); } \
+       ACCUMULATE void GlobalStats_update(entity this) { STAT(id, this) = (expr); } \
        STATIC_INIT(worldstat_##id) { entity this = STATS; STAT(id, this) = (expr); }
 #else
        #define REGISTER_STAT_2(id, type)
index 812eb72c8424bf2ab19f3d04fc30bf01522f3213..96e8a3a276258d568380219e0b1d8218ac9b7cf5 100644 (file)
@@ -4,6 +4,25 @@
 #include "sort.qh"
 #include "oo.qh"
 
+// string logic
+//
+// true: is truthy
+// == "": is equal to ""
+// is "": has the same string index as the string constant ""
+// strunzone: can be strunzoned
+//
+// |              | true | == "" | is "" | strunzone |
+// | :----------: | :--: | :---: | :---: | :-------: |
+// | nil          |      | yes   |       |           |
+// | strcat(nil)  | yes  | yes   |       |           |
+// | strzone(nil) | yes  | yes   |       | yes       |
+// | ""           | yes  | yes   | yes   |           |
+// | strcat("")   | yes  | yes   |       |           |
+// | strzone("")  | yes  | yes   |       | yes       |
+// | "s"          | yes  |       |       |           |
+// | strcat("s")  | yes  |       |       |           |
+// | strzone("s") | yes  |       |       | yes       |
+
 #ifdef CSQC
        float stringwidth_colors(string s, vector theSize)
        {
        }
 #endif
 
+#define strcpy(this, s) MACRO_BEGIN \
+       if (this) { \
+               strunzone(this); \
+       } \
+       this = strzone(s); \
+MACRO_END
+
+#define strfree(this) MACRO_BEGIN \
+       if (this) { \
+               strunzone(this); \
+       } \
+       this = string_null; \
+MACRO_END
+
 ERASEABLE
 string seconds_tostring(float sec)
 {
index ff6f2d23d5b52f1e00d75ba699c6552031ba8f5b..8d8de76ec6119abecd88093b0bd52bd8e1bb08e3 100644 (file)
@@ -5,7 +5,7 @@
 /** Use UpperCamelCase for suite and test only */
 #define TEST(suite, test) \
        void _TEST_##suite##_##test(); \
-       [[accumulate]] int TEST_RunAll_accumulated(int f) { \
+       ACCUMULATE int TEST_RunAll_accumulated(int f) { \
                if (!TEST_Run(#suite "_" #test)) ++f; \
                return = f; \
        } \
index 1572fec07cb2d1962870f63d7a3e3021db220841..2ad7bda2464b6842daa52fb70b2889c1835ab02c 100644 (file)
@@ -55,7 +55,7 @@ float url_URI_Get_Callback(int id, float status, string data)
                {
                        LOG_INFO("url_URI_Get_Callback: out of memory in buf_create");
                        e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
-                       strunzone(e.url_url);
+                       strfree(e.url_url);
                        delete(e);
                        return 1;
                }
@@ -64,7 +64,7 @@ float url_URI_Get_Callback(int id, float status, string data)
                {
                        LOG_INFO("url_URI_Get_Callback: out of memory in buf_create");
                        e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
-                       strunzone(e.url_url);
+                       strfree(e.url_url);
                        delete(e);
                        return 1;
                }
@@ -77,7 +77,7 @@ float url_URI_Get_Callback(int id, float status, string data)
        {
                // an ERROR
                e.url_ready(e, e.url_ready_pass, -fabs(status));
-               strunzone(e.url_url);
+               strfree(e.url_url);
                delete(e);
                return 1;
        }
@@ -108,7 +108,7 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
                                {
                                        LOG_INFO("url_single_fopen: out of memory in buf_create");
                                        rdy(e, pass, URL_READY_ERROR);
-                                       strunzone(e.url_url);
+                                       strfree(e.url_url);
                                        delete(e);
                                        return;
                                }
@@ -231,7 +231,7 @@ void url_fclose(entity e)
                                        LOG_INFO("url_fclose: too many concurrent requests");
                                        e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
                                        buf_del(e.url_wbuf);
-                                       strunzone(e.url_url);
+                                       strfree(e.url_url);
                                        delete(e);
                                        return;
                                }
@@ -243,7 +243,7 @@ void url_fclose(entity e)
                                LOG_INFO("url_fclose: failure in crypto_uri_postbuf");
                                e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
                                buf_del(e.url_wbuf);
-                               strunzone(e.url_url);
+                               strfree(e.url_url);
                                delete(e);
                                return;
                        }
@@ -264,7 +264,7 @@ void url_fclose(entity e)
                        // we have READ all data, just close
                        e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);
                        buf_del(e.url_rbuf);
-                       strunzone(e.url_url);
+                       strfree(e.url_url);
                        delete(e);
                }
        }
@@ -341,7 +341,7 @@ void url_multi_ready(entity fh, entity me, float status)
                {
                        LOG_INFO("uri_multi_ready: got HTTP error 422, data is in unusable format - not continuing");
                        me.url_ready(fh, me.url_ready_pass, status);
-                       strunzone(me.url_url);
+                       strfree(me.url_url);
                        delete(me);
                        return;
                }
@@ -350,7 +350,7 @@ void url_multi_ready(entity fh, entity me, float status)
                if (n <= me.url_attempt)
                {
                        me.url_ready(fh, me.url_ready_pass, status);
-                       strunzone(me.url_url);
+                       strfree(me.url_url);
                        delete(me);
                        return;
                }
index acbc1c61d4dda0f69cb0d256467f16bc2808cb07..4a7c8861069f7eb8420ec819b9525d606ffbe2d2 100644 (file)
@@ -63,11 +63,11 @@ float tanh(float e)
 
 float exp(float e)
 {
-       return (M_E ** e);
+       return pow(M_E, e);
 }
 float exp2(float e)
 {
-       return (2 ** e);
+       return pow(2, e);
 }
 float expm1(float e)
 {
@@ -79,16 +79,16 @@ vector frexp(float e)
        vector v;
        v.z = 0;
        v.y = ilogb(e) + 1;
-       v.x = e / (2 ** v.y);
+       v.x = e / pow(2, v.y);
        return v;
 }
 int ilogb(float e)
 {
        return floor(log2(fabs(e)));
 }
-float ldexp(float e, int e)
+float ldexp(float x, int e)
 {
-       return e * (2 ** e);
+       return x * pow(2, e);
 }
 float logn(float e, float base)
 {
@@ -117,12 +117,12 @@ vector modf(float f)
 
 float scalbn(float e, int n)
 {
-       return e * (2 ** n);
+       return e * pow(2, n);
 }
 
 float cbrt(float e)
 {
-       return copysign((fabs(e) ** (1.0/3.0)), e);
+       return copysign(pow(fabs(e), (1.0/3.0)), e);
 }
 float hypot(float e, float f)
 {
index a418dc2ce0fffa7b761fff860ebe8f950dbb09bf..d02f4661f5cd84bf891af26a6c1bef694244f463 100644 (file)
@@ -22,7 +22,7 @@
 
        void InputBox_setText(entity me, string txt)
        {
-               if (me.text) strunzone(me.text);
+               strfree(me.text);
                SUPER(InputBox).setText(me, strzone(txt));
        }
 
index d21b5676bd597d32da93d61b3f3a850d15d5af7b..f7a782dabbf877a3b0bcef5adee11db333d8edc0 100644 (file)
@@ -9,8 +9,7 @@
                me.text = txt;
                if (txt != me.currentText)
                {
-                       if (me.currentText) strunzone(me.currentText);
-                       me.currentText = strzone(txt);
+                       strcpy(me.currentText, txt);
                        me.recalcPos = 1;
                }
        }
                        t = me.textEntity.toString(me.textEntity);
                        if (t != me.currentText)
                        {
-                               if (me.currentText) strunzone(me.currentText);
-                               me.currentText = strzone(t);
+                               strcpy(me.currentText, t);
                                me.recalcPos = 1;
                        }
                }
index af14e0842b4dc749897a45e7fc2f18ae2dcaf6c4..fb6c4aeeda60a612cbe47ffe4c6804022b315c23 100644 (file)
@@ -217,8 +217,7 @@ void m_init_delayed()
        if (m_goto_buffer)
        {
                m_goto(m_goto_buffer);
-               strunzone(m_goto_buffer);
-               m_goto_buffer = string_null;
+               strfree(m_goto_buffer);
        }
 
        if (Menu_Active) m_display();  // delayed menu display
@@ -550,8 +549,7 @@ void m_tooltip(vector pos)
                        {
                                // fade out if tooltip of a certain item has changed
                                menuTooltipState = 3;
-                               if (prev_tooltip) strunzone(prev_tooltip);
-                               prev_tooltip = strzone(it.tooltip);
+                               strcpy(prev_tooltip, it.tooltip);
                        }
                        else if (menuTooltipItem && !m_testmousetooltipbox(pos))
                        {
@@ -584,8 +582,7 @@ void m_tooltip(vector pos)
 
                                        menuTooltipOrigin.x = -1;  // unallocated
 
-                                       if (menuTooltipText) strunzone(menuTooltipText);
-                                       menuTooltipText = strzone(gettooltip());
+                                       strcpy(menuTooltipText, gettooltip());
 
                                        int i = 0;
                                        float w = 0;
@@ -635,11 +632,7 @@ void m_tooltip(vector pos)
 
        if (menuTooltipItem == NULL)
        {
-               if (menuTooltipText)
-               {
-                       strunzone(menuTooltipText);
-                       menuTooltipText = string_null;
-               }
+               strfree(menuTooltipText);
                return;
        }
        else
@@ -953,8 +946,7 @@ void m_goto(string itemname)
 {
        if (!menuInitialized)
        {
-               if (m_goto_buffer) strunzone(m_goto_buffer);
-               m_goto_buffer = strzone(itemname);
+               strcpy(m_goto_buffer, itemname);
                return;
        }
        if (itemname == "")  // this can be called by GameCommand
index 0c5056b974673ce76b32958be25a4cb5e319611f..af1b7f6324ffaae82ade9eab7002e640aa63ce0e 100644 (file)
@@ -3,7 +3,7 @@
 #include <common/mutators/base.qh>
 
 // register all possible hooks here
+
 // to use a hook, first register your mutator using REGISTER_MUTATOR
 // then create your function using MUTATOR_HOOKFUNCTION
 
index cb418a4e1834fcce6076672f337e818fef681ca5..9f953f66f542f9a8b9238d65e813a6b5cdf777c7 100644 (file)
@@ -14,8 +14,7 @@ void rewrapCampaign(float w, float l0, float emptyheight, vector theFontSize)
        for(i = 0; i < campaign_entries; ++i)
        {
                l = l0;
-               if(campaign_longdesc_wrapped[i])
-                       strunzone(campaign_longdesc_wrapped[i]);
+               strfree(campaign_longdesc_wrapped[i]);
                n = tokenizebyseparator(campaign_longdesc[i], "\n");
                r = "";
                for(j = 0; j < n; ++j)
@@ -70,12 +69,8 @@ void XonoticCampaignList_destroy(entity me)
 void XonoticCampaignList_loadCvars(entity me)
 {
        // read campaign cvars
-       if(campaign_name)
-               strunzone(campaign_name);
-       if(me.cvarName)
-               strunzone(me.cvarName);
-       campaign_name = strzone(cvar_string("g_campaign_name"));
-       me.cvarName = strzone(strcat("g_campaign", campaign_name, "_index"));
+       strcpy(campaign_name, cvar_string("g_campaign_name"));
+       strcpy(me.cvarName, strcat("g_campaign", campaign_name, "_index"));
        registercvar(me.cvarName, "", 0); // saved by server QC anyway
        CampaignFile_Unload();
        CampaignFile_Load(0, CAMPAIGN_MAX_ENTRIES);
index e11d7dcc0f04d4f9401edbb4d16273b823162542..f3c3fe24fa48ee237b2be4c277b5a0a912f1254f 100644 (file)
@@ -25,9 +25,7 @@ void XonoticCrosshairPreview_draw(entity me)
        float a;
        rgb = stov(cvar_string("crosshair_color"));
        a = cvar("crosshair_alpha");
-       if(me.src)
-               strunzone(me.src);
-       me.src = strzone(strcat("/gfx/crosshair", cvar_string("crosshair")));
+       strcpy(me.src, strcat("/gfx/crosshair", cvar_string("crosshair")));
 
        sz = draw_PictureSize(me.src);
        sz = globalToBoxSize(sz, me.size);
index 12bb2810ba87282e54d9df9c43b7df5e1dba38c1..9587d5432d83c7ebc80dcbac53a26dfc0af370e8 100644 (file)
@@ -107,17 +107,10 @@ void XonoticCvarList_setSelected(entity me, float i)
        if(me.nItems == 0)
                return;
 
-       if(me.cvarName)
-               strunzone(me.cvarName);
-       if(me.cvarDescription)
-               strunzone(me.cvarDescription);
-       if(me.cvarType)
-               strunzone(me.cvarType);
-       if(me.cvarDefault)
-               strunzone(me.cvarDefault);
-       me.cvarName = strzone(bufstr_get(me.handle, me.selectedItem));
-       me.cvarDescription = strzone(cvar_description(me.cvarName));
-       me.cvarDefault = strzone(cvar_defstring(me.cvarName));
+       strfree(me.cvarType);
+       strcpy(me.cvarName, bufstr_get(me.handle, me.selectedItem));
+       strcpy(me.cvarDescription, cvar_description(me.cvarName));
+       strcpy(me.cvarDefault, cvar_defstring(me.cvarName));
        me.cvarNameBox.setText(me.cvarNameBox, me.cvarName);
        me.cvarDescriptionBox.setText(me.cvarDescriptionBox, me.cvarDescription);
        float needsForcing = me.updateCvarType(me);
index b527542a5965b1408ed6e299c856ccb414b846df..16d5370f5d7beeef0487001e7aae4c7ad76bb77c 100644 (file)
@@ -129,8 +129,7 @@ void DemoList_Refresh_Click(entity btn, entity me)
 
 void DemoList_Filter_Change(entity box, entity me)
 {
-       if(me.filterString)
-               strunzone(me.filterString);
+       strfree(me.filterString);
 
        if(box.text != "")
        {
index 481914200a99f625338e4be2466d158a1e5bcd34..2a2144598bbfecd56097c0a8efea20b4918228fd 100644 (file)
@@ -27,16 +27,8 @@ void GameType_ConfigureSliders(entity me, string pLabel, float pMin, float pMax,
        // clear old values
        for(i = 0; i < e.nValues; ++i);
        {
-               if(e.(valueStrings[i]))
-               {
-                       strunzone(e.(valueStrings[i]));
-                       e.(valueStrings[i]) = string_null;
-               }
-               if(e.(valueIdentifiers[i]))
-               {
-                       strunzone(e.(valueIdentifiers[i]));
-                       e.(valueIdentifiers[i]) = string_null;
-               }
+               strfree(e.(valueStrings[i]));
+               strfree(e.(valueIdentifiers[i]));
        }
        e.clearValues(e);
 
index 2f2ab901a84239a9c37c21866552b449f7089ed6..87ffadf3831d8015641eb7b3b9e50e7d8e95ecc7 100644 (file)
@@ -12,19 +12,11 @@ void XonoticMapInfoDialog_loadMapInfo(entity me, int i, entity mlb)
        me.startButton.onClickEntity = mlb;
        MapInfo_Get_ByID(i);
 
-       if(me.currentMapBSPName)
-       {
-               strunzone(me.currentMapBSPName);
-               strunzone(me.currentMapTitle);
-               strunzone(me.currentMapAuthor);
-               strunzone(me.currentMapDescription);
-               strunzone(me.currentMapPreviewImage);
-       }
-       me.currentMapBSPName = strzone(MapInfo_Map_bspname);
-       me.currentMapTitle = strzone(strdecolorize(MapInfo_Map_title));
-       me.currentMapAuthor = strzone(strdecolorize(MapInfo_Map_author));
-       me.currentMapDescription = strzone(MapInfo_Map_description);
-       me.currentMapPreviewImage = strzone(strcat("/maps/", MapInfo_Map_bspname));
+       strcpy(me.currentMapBSPName, MapInfo_Map_bspname);
+       strcpy(me.currentMapTitle, strdecolorize(MapInfo_Map_title));
+       strcpy(me.currentMapAuthor, strdecolorize(MapInfo_Map_author));
+       strcpy(me.currentMapDescription, MapInfo_Map_description);
+       strcpy(me.currentMapPreviewImage, strcat("/maps/", MapInfo_Map_bspname));
 
        me.frame.setText(me.frame, me.currentMapBSPName);
        me.titleLabel.setText(me.titleLabel, me.currentMapTitle);
index 022bed03d52912ce05e35a245f0dba12255524ae..994c5a7c95cc3f44ff03e6e842aad3ff864a7f2c 100644 (file)
@@ -30,12 +30,8 @@ string WeaponArenaString()
                return _("Most Weapons Arena");
        if(s == weaponarenastring_cvar)
                return weaponarenastring;
-       if(weaponarenastring)
-               strunzone(weaponarenastring);
-       if(weaponarenastring_cvar)
-               strunzone(weaponarenastring_cvar);
 
-       weaponarenastring_cvar = strzone(s);
+       strcpy(weaponarenastring_cvar, s);
 
        n = tokenize_console(s);
        s = "";
@@ -48,7 +44,7 @@ string WeaponArenaString()
        }
        s = sprintf(_("%s Arena"), s);
 
-       weaponarenastring = strzone(s);
+       strcpy(weaponarenastring, s);
 
        return weaponarenastring;
 }
index baeb9a51bcbf127d14f8dc89acb36b6814ab5901..5745ce072e044940ddadd3d2e19dd41875e65dbb 100644 (file)
@@ -16,61 +16,21 @@ void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
        // ====================================
        //  First clear and unzone the strings
        // ====================================
-       if(me.currentServerName)
-               strunzone(me.currentServerName);
-       me.currentServerName = string_null;
-
-       if(me.currentServerCName)
-               strunzone(me.currentServerCName);
-       me.currentServerCName = string_null;
-
-       if(me.currentServerType)
-               strunzone(me.currentServerType);
-       me.currentServerType = string_null;
-
-       if(me.currentServerMap)
-               strunzone(me.currentServerMap);
-       me.currentServerMap = string_null;
-
-       if(me.currentServerPlayers)
-               strunzone(me.currentServerPlayers);
-       me.currentServerPlayers = string_null;
-
-       if(me.currentServerNumPlayers)
-               strunzone(me.currentServerNumPlayers);
-       me.currentServerNumPlayers = string_null;
-
-       if(me.currentServerNumBots)
-               strunzone(me.currentServerNumBots);
-       me.currentServerNumBots = string_null;
-
-       if(me.currentServerNumFreeSlots)
-               strunzone(me.currentServerNumFreeSlots);
-       me.currentServerNumFreeSlots = string_null;
-
-       if(me.currentServerMod)
-               strunzone(me.currentServerMod);
-       me.currentServerMod = string_null;
-
-       if(me.currentServerVersion)
-               strunzone(me.currentServerVersion);
-       me.currentServerVersion = string_null;
-
+       strfree(me.currentServerName);
+       strfree(me.currentServerCName);
+       strfree(me.currentServerType);
+       strfree(me.currentServerMap);
+       strfree(me.currentServerPlayers);
+       strfree(me.currentServerNumPlayers);
+       strfree(me.currentServerNumBots);
+       strfree(me.currentServerNumFreeSlots);
+       strfree(me.currentServerMod);
+       strfree(me.currentServerVersion);
        // not zoned!
-       //if(me.currentServerEncrypt)
-       //      strunzone(me.currentServerEncrypt);
-       //me.currentServerEncrypt = string_null;
-       if(me.currentServerPure)
-               strunzone(me.currentServerPure);
-       me.currentServerPure = string_null;
-
-       if(me.currentServerKey)
-               strunzone(me.currentServerKey);
-       me.currentServerKey = string_null;
-
-       if(me.currentServerID)
-               strunzone(me.currentServerID);
-       me.currentServerID = string_null;
+       //      strfree(me.currentServerEncrypt);
+       strfree(me.currentServerPure);
+       strfree(me.currentServerKey);
+       strfree(me.currentServerID);
 
        // ==========================
        //  Now, fill in the strings
index 1229be714491116f7348641b47f7d31fd2310126..afde0914a48b981db347492f8db456e31ae4da64 100644 (file)
@@ -19,9 +19,7 @@ void XonoticScreenshotBrowserTab_loadPreviewScreenshot(entity me, string scrImag
 {
        if (me.currentScrPath == scrImage)
                return;
-       if (me.currentScrPath)
-               strunzone(me.currentScrPath);
-       me.currentScrPath = strzone(scrImage);
+       strcpy(me.currentScrPath, scrImage);
        me.screenshotImage.load(me.screenshotImage, me.currentScrPath);
 }
 void XonoticScreenshotBrowserTab_fill(entity me)
index d6d545eeeaf00b939ce5b8ad35b6243bd8e66868..57dd75679e03b3d272432dbe79088261220e4c87 100644 (file)
@@ -24,9 +24,7 @@ void XonoticScreenshotViewerDialog_loadScreenshot(entity me, string scrImage)
 
        if (me.currentScrPath == scrImage)
                return;
-       if (me.currentScrPath)
-               strunzone(me.currentScrPath);
-       me.currentScrPath = strzone(scrImage);
+       strcpy(me.currentScrPath, scrImage);
        me.screenshotImage.load(me.screenshotImage, me.currentScrPath);
        me.frame.setText(me.frame, me.screenshotImage.screenshotTitle);
 }
index 66c96046d88e9e4a2b156b2ed2d149188613ab22..d97d7131a473b36c0a46e8935b1efba6078c51d9 100644 (file)
@@ -188,19 +188,15 @@ void HUDSkinList_Refresh_Click(entity btn, entity me)
 
 void HUDSkinList_SavedName_Change(entity box, entity me)
 {
-       if(me.savedName)
-               strunzone(me.savedName);
+       strfree(me.savedName);
 
        if(box.text != "")
                me.savedName = strzone(box.text);
-       else
-               me.savedName = string_null;
 }
 
 void HUDSkinList_Filter_Change(entity box, entity me)
 {
-       if(me.filterString)
-               strunzone(me.filterString);
+       strfree(me.filterString);
 
        if(box.text != "")
        {
@@ -209,8 +205,6 @@ void HUDSkinList_Filter_Change(entity box, entity me)
                else
                        me.filterString = strzone(strcat("*", box.text, "*"));
        }
-       else
-               me.filterString = string_null;
 
        me.getHUDSkins(me);
 }
index 1f28a1bdfede23aa181f110ca297596457a85976..cde80d693d422a6a44b1664cd06f29fa7ceee87d 100644 (file)
@@ -246,12 +246,8 @@ void XonoticKeyBinder_destroy(entity me)
 
        for(int i = 0; i < MAX_KEYBINDS; ++i)
        {
-               if(Xonotic_KeyBinds_Functions[i])
-                       strunzone(Xonotic_KeyBinds_Functions[i]);
-               Xonotic_KeyBinds_Functions[i] = string_null;
-               if(Xonotic_KeyBinds_Descriptions[i])
-                       strunzone(Xonotic_KeyBinds_Descriptions[i]);
-               Xonotic_KeyBinds_Descriptions[i] = string_null;
+               strfree(Xonotic_KeyBinds_Functions[i]);
+               strfree(Xonotic_KeyBinds_Descriptions[i]);
        }
        Xonotic_KeyBinds_Count = 0;
 }
index 111744e9668da9e0b3909f7c97e15c8f01062e72..73ef8a32ae8cfd738852859b0ccb47fa5bf6bbd0 100644 (file)
@@ -181,8 +181,6 @@ void XonoticMapList_refilter(entity me)
 
        for(i = 0; i < MapInfo_count; ++i)
                draw_PreloadPicture(strcat("/maps/", MapInfo_BSPName_ByID(i)));
-       if(me.g_maplistCache)
-               strunzone(me.g_maplistCache);
        s = "0";
        for(i = 1; i < MapInfo_count; i *= 2)
                s = strcat(s, s);
@@ -201,7 +199,7 @@ void XonoticMapList_refilter(entity me)
                                );
                }
        }
-       me.g_maplistCache = strzone(s);
+       strcpy(me.g_maplistCache, s);
        if(gt != me.lastGametype || f != me.lastFeatures)
        {
                me.lastGametype = gt;
@@ -217,12 +215,9 @@ void XonoticMapList_refilterCallback(entity me, entity cb)
 
 void MapList_StringFilterBox_Change(entity box, entity me)
 {
-       if(me.stringFilter)
-               strunzone(me.stringFilter);
+       strfree(me.stringFilter);
        if(box.text != "")
                me.stringFilter = strzone(box.text);
-       else
-               me.stringFilter = string_null;
 
        me.refilter(me);
 }
@@ -345,9 +340,7 @@ float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift)
                if(time < me.typeToSearchTime)
                {
                        save = substring(me.typeToSearchString, 0, strlen(me.typeToSearchString) - 1);
-                       if(me.typeToSearchString)
-                               strunzone(me.typeToSearchString);
-                       me.typeToSearchString = strzone(save);
+                       strcpy(me.typeToSearchString, save);
                        me.typeToSearchTime = time + 0.5;
                        if(strlen(me.typeToSearchString))
                        {
@@ -364,9 +357,7 @@ float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift)
                        save = ch;
                else
                        save = strcat(me.typeToSearchString, ch);
-               if(me.typeToSearchString)
-                       strunzone(me.typeToSearchString);
-               me.typeToSearchString = strzone(save);
+               strcpy(me.typeToSearchString, save);
                me.typeToSearchTime = time + 0.5;
                MapInfo_FindName(me.typeToSearchString);
                if(MapInfo_FindName_firstResult >= 0)
index c679d4449d7177598dc649228f7e4cc96b11be76..1ad651bdb5a5824deef0e972601fd469fadb7fb4 100644 (file)
@@ -113,21 +113,12 @@ void XonoticPlayerModelSelector_go(entity me, float d)
 {
        me.idxModels = mod(me.idxModels + d + me.numModels, me.numModels);
 
-       if(me.currentModel)
-               strunzone(me.currentModel);
-       if(me.currentModelTitle)
-               strunzone(me.currentModelTitle);
-       if(me.currentModelImage)
-               strunzone(me.currentModelImage);
-       if(me.currentModelDescription)
-               strunzone(me.currentModelDescription);
-
        // select model #i!
-       me.currentModelTitle = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_TITLE));
-       me.currentModelImage = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_IMAGE));
+       strcpy(me.currentModelTitle, bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_TITLE));
+       strcpy(me.currentModelImage, bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_IMAGE));
        me.currentSkin = stof(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_SKIN));
-       me.currentModel = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_MODEL));
-       me.currentModelDescription = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_DESC));
+       strcpy(me.currentModel, bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_MODEL));
+       strcpy(me.currentModelDescription, bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_DESC));
 
        // fix the image
        if(draw_PictureSize(me.currentModelImage) == '0 0 0')
index 8e8f3ccf738bd4f32de72be843b87510b558d8d8..af987e7b58c9ab78491ef7829a8e57a1885842f5 100644 (file)
@@ -19,9 +19,7 @@ void XonoticScreenshotImage_load(entity me, string theImage)
 {
        me.screenshotTime = time;
        me.src = theImage;
-       if (me.screenshotTitle)
-               strunzone(me.screenshotTitle);
-       me.screenshotTitle = strzone(substring(me.src, 13, strlen(theImage) - 13)); //strip "/screenshots/"
+       strcpy(me.screenshotTitle, substring(me.src, 13, strlen(theImage) - 13)); //strip "/screenshots/"
 
        me.initZoom(me); // this image may have a different size
        me.setZoom(me, 0, 0);
index a948ce86f842dfb79d7bf85c631835fcc6bf751b..de0adc793815796c0e175f32bf1e6e473b2709e1 100644 (file)
@@ -153,8 +153,7 @@ void ScreenshotList_Refresh_Click(entity btn, entity me)
 
 void ScreenshotList_Filter_Change(entity box, entity me)
 {
-       if(me.filterString)
-               strunzone(me.filterString);
+       strfree(me.filterString);
 
        if(box.text != "")
        {
@@ -163,8 +162,6 @@ void ScreenshotList_Filter_Change(entity box, entity me)
                else
                        me.filterString = strzone(strcat("*", box.text, "*"));
        }
-       else
-               me.filterString = string_null;
 
        ScreenshotList_Refresh_Click(NULL, me);
 }
index 5e6a567b6af907de399757b63a265675d265d340..503a975c326fe09ba82aab79ac0b5131d6cb41a5 100644 (file)
@@ -37,8 +37,7 @@ void RegisterSLCategories()
                                } } \
                                if(catnum) \
                                { \
-                                       strunzone(categories[i].override_string); \
-                                       categories[i].override_string = string_null; \
+                                       strfree(categories[i].override_string); \
                                        categories[i].override_field = catnum; \
                                        continue; \
                                } \
@@ -51,8 +50,7 @@ void RegisterSLCategories()
                                        ); \
                                } \
                        } \
-                       strunzone(categories[i].override_string); \
-                       categories[i].override_string = string_null; \
+                       strfree(categories[i].override_string); \
                        categories[i].override_field = 0; \
                }
        PROCESS_OVERRIDE(cat_enoverride_string, cat_enoverride)
@@ -308,9 +306,7 @@ void XonoticServerList_setSelected(entity me, int i)
        if(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT) != me.nItems)
                return; // sorry, it would be wrong
 
-       if(me.selectedServer)
-               strunzone(me.selectedServer);
-       me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
+       strcpy(me.selectedServer, gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
 
        me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer);
        me.ipAddressBox.cursorPos = strlen(me.selectedServer);
@@ -549,9 +545,9 @@ void XonoticServerList_draw(entity me)
        }
        else { me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); }
 
-       me.connectButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == ""));
-       me.infoButton.disabled = ((me.nItems == 0) || !owned);
-       me.favoriteButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == ""));
+       me.connectButton.disabled = (me.lockedSelectedItem || (me.nItems == 0 && me.ipAddressBox.text == ""));
+       me.infoButton.disabled = (me.lockedSelectedItem || me.nItems == 0 || !owned);
+       me.favoriteButton.disabled = (me.lockedSelectedItem || (me.nItems == 0 && me.ipAddressBox.text == ""));
 
        if(me.lockedSelectedItem)
        {
@@ -559,9 +555,7 @@ void XonoticServerList_draw(entity me)
                {
                        if(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem) != me.selectedServer)
                        {
-                               if(me.selectedServer)
-                                       strunzone(me.selectedServer);
-                               me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
+                               strcpy(me.selectedServer, gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
                        }
                        found = true;
                }
@@ -586,9 +580,7 @@ void XonoticServerList_draw(entity me)
                        // selected server disappeared, select the last server (scrolling to it)
                        if(me.selectedItem >= me.nItems)
                                SUPER(XonoticServerList).setSelected(me, me.nItems - 1);
-                       if(me.selectedServer)
-                               strunzone(me.selectedServer);
-                       me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
+                       strcpy(me.selectedServer, gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
                }
        }
 
@@ -666,12 +658,9 @@ void ServerList_TypeSort_Click(entity btn, entity me)
 }
 void ServerList_Filter_Change(entity box, entity me)
 {
-       if(me.filterString)
-               strunzone(me.filterString);
+       strfree(me.filterString);
        if(box.text != "")
                me.filterString = strzone(box.text);
-       else
-               me.filterString = string_null;
        me.refreshServerList(me, REFRESHSERVERLIST_REFILTER);
 
        me.ipAddressBox.setText(me.ipAddressBox, "");
@@ -717,9 +706,7 @@ void XonoticServerList_setSortOrder(entity me, int fld, int direction)
        me.sortButton4.forcePressed = 0;
        me.sortButton5.forcePressed = (fld == SLIST_FIELD_NUMHUMANS);
        me.selectedItem = 0;
-       if(me.selectedServer)
-               strunzone(me.selectedServer);
-       me.selectedServer = string_null;
+       strfree(me.selectedServer);
        me.refreshServerList(me, REFRESHSERVERLIST_REFILTER);
 }
 void XonoticServerList_positionSortButton(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc)
@@ -775,11 +762,10 @@ void XonoticServerList_resizeNotify(entity me, vector relOrigin, vector relSize,
 }
 void ServerList_Connect_Click(entity btn, entity me)
 {
-       localcmd(sprintf("connect %s\n",
-               ((me.ipAddressBox.text != "") ?
-                       me.ipAddressBox.text : me.selectedServer
-               )
-       ));
+       if (me.lockedSelectedItem)
+               return;
+       string sv = (me.ipAddressBox.text != "") ? me.ipAddressBox.text : me.selectedServer;
+       localcmd(sprintf("connect %s\n", sv));
 }
 void ServerList_Favorite_Click(entity btn, entity this)
 {
@@ -857,7 +843,7 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
                }
        }
 
-       if(isSelected)
+       if(isSelected && !me.lockedSelectedItem)
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
        else if(isFocused)
        {
index e45abfda33b528cce9e9e72035dd4ab1807d47c5..32359ad2b22edf9abf652201b8e8c6a6b199c217 100644 (file)
@@ -30,7 +30,7 @@ CLASS(XonoticServerList, XonoticListBox)
        ATTRIB(XonoticServerList, columnTypeSize, float, 0);
        ATTRIB(XonoticServerList, columnPlayersOrigin, float, 0);
        ATTRIB(XonoticServerList, columnPlayersSize, float, 0);
-       ATTRIB(XonoticServerList, lockedSelectedItem, bool, true);      // initially keep selected the first item of the list, avoiding an unwanted scrolling
+       ATTRIB(XonoticServerList, lockedSelectedItem, bool, true); // initially keep selected the first item of the list to avoid unwanted scrolling
 
        ATTRIB(XonoticServerList, selectedServer, string); // to restore selected server when needed
        METHOD(XonoticServerList, setSelected, void(entity, float));
index 13e6ba34c03395f74fbe2f7f6fccfa3c26fd16f6..6d77e1adf929c1e94f2aa964c7edb7bff88837da 100644 (file)
@@ -104,13 +104,10 @@ void SoundList_Menu_Track_Reset(entity box, entity me)
 
 void SoundList_Filter_Change(entity box, entity me)
 {
-       if(me.filterString)
-               strunzone(me.filterString);
+       strfree(me.filterString);
 
        if(box.text != "")
                me.filterString = strzone(box.text);
-       else
-               me.filterString = string_null;
 
        me.getSounds(me);
 }
index 602862820b114f93a4ef00bd28ceb07a4e453e1f..c9cd001ba9f9fcd4ec2fdc79727b31e8c6684e7b 100644 (file)
@@ -267,8 +267,7 @@ void setZonedTooltip(entity e, string theTooltip, string theCvar)
                theTooltip = string_null;
        }
 
-       if(e.tooltip)
-               strunzone(e.tooltip);
+       strfree(e.tooltip);
        e.tooltip = (theTooltip != "") ? strzone(theTooltip) : string_null;
 }
 
@@ -612,8 +611,7 @@ void preMenuDraw()
        }
        else
        {
-               strunzone(campaign_name_previous);
-               campaign_name_previous = strzone(campaign_name);
+               strcpy(campaign_name_previous, campaign_name);
                campaign_won_previous = cvar(strcat("g_campaign", campaign_name, "_won"));
        }
 }
index fd4f51385bb898cf74fd498b1bc13b3673c02805..695b2d7873144974af98443e14ca3f36dd680141 100644 (file)
@@ -21,9 +21,8 @@ void XonoticWeaponarenaCheckBox_setChecked(entity me, float foo)
 }
 void XonoticWeaponarenaCheckBox_loadCvars(entity me)
 {
-       float n = tokenize_console(cvar_string("menu_weaponarena"));
-       float i;
-       for(i=0; i<n; ++i)
+       int n = tokenize_console(cvar_string("menu_weaponarena"));
+       for (int i = 0; i < n; i++)
        {
                if(argv(i) == me.netname)
                {
index e9bacafa7d1ffd650045e23cded798ce46cbcce5..c1abd004105df81edf5525d4bb705912e3e1ba56 100644 (file)
@@ -167,7 +167,7 @@ int autocvar_g_maxplayers;
 float autocvar_g_maxplayers_spectator_blocktime;
 float autocvar_g_maxpushtime;
 float autocvar_g_maxspeed;
-bool autocvar_g_instagib;
+#define autocvar_g_instagib cvar("g_instagib")
 #define autocvar_g_mirrordamage cvar("g_mirrordamage")
 #define autocvar_g_mirrordamage_virtual cvar("g_mirrordamage_virtual")
 bool autocvar_g_mirrordamage_onlyweapons;
@@ -240,6 +240,7 @@ float autocvar_g_turrets_targetscan_mindelay;
 bool autocvar_g_use_ammunition;
 bool autocvar_g_waypointeditor;
 bool autocvar_g_waypointeditor_symmetrical;
+bool autocvar_g_waypointeditor_symmetrical_allowload = true;
 vector autocvar_g_waypointeditor_symmetrical_origin;
 int autocvar_g_waypointeditor_symmetrical_order;
 vector autocvar_g_waypointeditor_symmetrical_axis;
index a605fc0689e73259ba266cd41047ca573bb252ad..b4272e3e0648224f6de70f8a1e2bd8f871bb0b5c 100644 (file)
@@ -396,18 +396,10 @@ void bot_clientdisconnect(entity this)
        if (!IS_BOT_CLIENT(this))
                return;
        bot_clearqueue(this);
-       if(this.cleanname)
-               strunzone(this.cleanname);
-       if(this.netname_freeme)
-               strunzone(this.netname_freeme);
-       if(this.playermodel_freeme)
-               strunzone(this.playermodel_freeme);
-       if(this.playerskin_freeme)
-               strunzone(this.playerskin_freeme);
-       this.cleanname = string_null;
-       this.netname_freeme = string_null;
-       this.playermodel_freeme = string_null;
-       this.playerskin_freeme = string_null;
+       strfree(this.cleanname);
+       strfree(this.netname_freeme);
+       strfree(this.playermodel_freeme);
+       strfree(this.playerskin_freeme);
        if(this.bot_cmd_current)
                delete(this.bot_cmd_current);
        if(bot_waypoint_queue_owner == this)
index e69050beb84d16e438e12f5849184139f792195c..82d82cb590f3835dbc0691ae7b17840176adfd00 100644 (file)
@@ -308,9 +308,7 @@ float bot_decodecommand(string cmdstring)
                                bot_cmd.bot_cmd_parm_float = stof(parm);
                                break;
                        case BOT_CMD_PARAMETER_STRING:
-                               if(bot_cmd.bot_cmd_parm_string)
-                                       strunzone(bot_cmd.bot_cmd_parm_string);
-                               bot_cmd.bot_cmd_parm_string = strzone(parm);
+                               strcpy(bot_cmd.bot_cmd_parm_string, parm);
                                break;
                        case BOT_CMD_PARAMETER_VECTOR:
                                if(substring(parm, 0, 1) != "\'")
@@ -1170,8 +1168,7 @@ void bot_resetqueues()
                it.bot_barrier = 0;
                for(int i = 0; i < it.bot_places_count; ++i)
                {
-                       strunzone(it.(bot_placenames[i]));
-                       it.(bot_placenames[i]) = string_null;
+                       strfree(it.(bot_placenames[i]));
                }
                it.bot_places_count = 0;
        });
index fa82d926b63e92776cfd293dbebccf15ba20ad04..384f1e7ce1c87ddebc1d048a8838d69181f051a6 100644 (file)
@@ -1028,10 +1028,33 @@ void waypoint_saveall()
                return;
        }
 
-       // add 3 comments to not break compatibility with older Xonotic versions
+       float sym = autocvar_g_waypointeditor_symmetrical;
+       string sym_str = ftos(sym);
+       if (sym == -1 || (sym == 1 && autocvar_g_waypointeditor_symmetrical_order >= 2))
+       {
+               if (sym == 1)
+               {
+                       sym_str = cons(sym_str, "-");
+                       sym_str = cons(sym_str, "-");
+               }
+               else
+               {
+                       sym_str = cons(sym_str, ftos(autocvar_g_waypointeditor_symmetrical_origin.x));
+                       sym_str = cons(sym_str, ftos(autocvar_g_waypointeditor_symmetrical_origin.y));
+               }
+               if (autocvar_g_waypointeditor_symmetrical_order >= 2)
+                       sym_str = cons(sym_str, ftos(autocvar_g_waypointeditor_symmetrical_order));
+       }
+       else if (autocvar_g_waypointeditor_symmetrical == -2)
+       {
+               sym_str = cons(sym_str, ftos(autocvar_g_waypointeditor_symmetrical_axis.x));
+               sym_str = cons(sym_str, ftos(autocvar_g_waypointeditor_symmetrical_axis.y));
+       }
+
+       // a group of 3 comments doesn't break compatibility with older Xonotic versions
        // (they are read as a waypoint with origin '0 0 0' and flag 0 though)
        fputs(file, strcat("//", "WAYPOINT_VERSION ", ftos_decimals(WAYPOINT_VERSION, 2), "\n"));
-       fputs(file, strcat("//", "\n"));
+       fputs(file, strcat("//", "WAYPOINT_SYMMETRY ", sym_str, "\n"));
        fputs(file, strcat("//", "\n"));
 
        int c = 0;
@@ -1085,6 +1108,8 @@ float waypoint_loadall()
 
        bool parse_comments = true;
        float ver = 0;
+       float sym = 0;
+       float sym_param1 = 0, sym_param2 = 0, sym_param3 = 0;
 
        while ((s = fgets(file)))
        {
@@ -1094,6 +1119,14 @@ float waypoint_loadall()
                        {
                                if(substring(s, 2, 17) == "WAYPOINT_VERSION ")
                                        ver = stof(substring(s, 19, -1));
+                               else if(substring(s, 2, 18) == "WAYPOINT_SYMMETRY ")
+                               {
+                                       int tokens = tokenizebyseparator(substring(s, 20, -1), " ");
+                                       if (tokens) { sym = stof(argv(0)); }
+                                       if (tokens > 1) { sym_param1 = stof(argv(1)); }
+                                       if (tokens > 2) { sym_param2 = stof(argv(2)); }
+                                       if (tokens > 3) { sym_param3 = stof(argv(3)); }
+                               }
                                continue;
                        }
                        else
@@ -1124,6 +1157,35 @@ float waypoint_loadall()
        fclose(file);
        LOG_TRACE("loaded ", ftos(cwp), " waypoints and ", ftos(cwb), " wayboxes from maps/", mapname, ".waypoints");
 
+       if (autocvar_g_waypointeditor && autocvar_g_waypointeditor_symmetrical_allowload)
+       {
+               cvar_set("g_waypointeditor_symmetrical", ftos(sym));
+               if (sym == 1 && sym_param3 < 2)
+                       cvar_set("g_waypointeditor_symmetrical_order", "0"); // make sure this is reset if not loaded
+               if (sym == -1 || (sym == 1 && sym_param3 >= 2))
+               {
+                       string params;
+                       if (sym == 1)
+                               params = cons("-", "-");
+                       else
+                       {
+                               params = cons(ftos(sym_param1), ftos(sym_param2));
+                               cvar_set("g_waypointeditor_symmetrical_origin", params);
+                       }
+                       cvar_set("g_waypointeditor_symmetrical_order", ftos(sym_param3));
+                       LOG_INFO("Waypoint editor: loaded symmetry ", ftos(sym), " with origin ", params, " and order ", ftos(sym_param3));
+               }
+               else if (sym == -2)
+               {
+                       string params = strcat(ftos(sym_param1), " ", ftos(sym_param2));
+                       cvar_set("g_waypointeditor_symmetrical_axis", params);
+                       LOG_INFO("Waypoint editor: loaded symmetry ", ftos(sym), " with axis ", params);
+               }
+               else
+                       LOG_INFO("Waypoint editor: loaded symmetry ", ftos(sym));
+               LOG_INFO(strcat("g_waypointeditor_symmetrical", " has been set to ", cvar_string("g_waypointeditor_symmetrical")));
+       }
+
        return cwp + cwb;
 }
 
index bea11e9299986ce180765f09a520e37c8295f6de..595c2d058fcc1cd82fa1a082ffd29096f90adc3b 100644 (file)
@@ -6,7 +6,7 @@
 // increase by 0.01 when changes require only waypoint relinking
 // increase by 1 when changes require to manually edit waypoints
 // max 2 decimal places, always specified
-#define WAYPOINT_VERSION 1.00
+#define WAYPOINT_VERSION 1.01
 
 // fields you can query using prvm_global server to get some statistics about waypoint linking culling
 float relink_total, relink_walkculled, relink_pvsculled, relink_lengthculled;
index e80769cc2783edabcca7b1952aafbb5f9b06a256..e90d6660352a28d0f62415cdd2d769110e8495d7 100644 (file)
@@ -52,8 +52,7 @@ void cvar_set_campaignwrapper(string theCvar, string theValue)
 {
        if(cvar_string_campaignwrapper(theCvar) == theValue)
                return;
-       string s;
-       s = cvar_campaignwrapper_list;
+       string s = cvar_campaignwrapper_list;
        cvar_campaignwrapper_list = strzone(strcat("; ", theCvar, " ", theValue, s));
        strunzone(s);
        //print(cvar_campaignwrapper_list, "\n");
index 317713b4f53528c6a120bf2f9a891749b8462df7..d374876d0456441bc59fdf69fe683a643bb8d42a 100644 (file)
@@ -1352,8 +1352,8 @@ void ClientDisconnect(entity this)
 
     MUTATOR_CALLHOOK(ClientDisconnect, this);
 
-       if (CS(this).netname_previous) strunzone(CS(this).netname_previous); // needs to be before the CS entity is removed!
-       if (CS(this).weaponorder_byimpulse) strunzone(CS(this).weaponorder_byimpulse);
+       strfree(CS(this).netname_previous); // needs to be before the CS entity is removed!
+       strfree(CS(this).weaponorder_byimpulse);
        ClientState_detach(this);
 
        Portal_ClearAll(this);
@@ -1373,7 +1373,7 @@ void ClientDisconnect(entity this)
 
        bot_relinkplayerlist();
 
-       if (this.clientstatus) strunzone(this.clientstatus);
+       strfree(this.clientstatus);
        if (this.personal) delete(this.personal);
 
        this.playerid = 0;
@@ -1496,7 +1496,7 @@ void player_powerups(entity this)
        Fire_ApplyDamage(this);
        Fire_ApplyEffect(this);
 
-       if (!g_instagib)
+       if (!autocvar_g_instagib)
        {
                if (this.items & ITEM_Strength.m_itemid)
                {
@@ -2246,43 +2246,6 @@ bool PlayerThink(entity this)
                return false;
        }
 
-       bool have_hook = false;
-       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-       {
-               .entity weaponentity = weaponentities[slot];
-               if(this.(weaponentity).hook.state)
-               {
-                       have_hook = true;
-                       break;
-               }
-       }
-       bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
-       if (have_hook) {
-               do_crouch = false;
-       //} else if (this.waterlevel >= WATERLEVEL_SWIMMING) {
-               //do_crouch = false;
-       } else if (this.vehicle) {
-               do_crouch = false;
-       } else if (STAT(FROZEN, this)) {
-               do_crouch = false;
-    }
-
-       if (do_crouch) {
-               if (!this.crouch) {
-                       this.crouch = true;
-                       this.view_ofs = STAT(PL_CROUCH_VIEW_OFS, this);
-                       setsize(this, STAT(PL_CROUCH_MIN, this), STAT(PL_CROUCH_MAX, this));
-                       // setanim(this, this.anim_duck, false, true, true); // this anim is BROKEN anyway
-               }
-       } else if (this.crouch) {
-        tracebox(this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), this.origin, false, this);
-        if (!trace_startsolid) {
-            this.crouch = false;
-            this.view_ofs = STAT(PL_VIEW_OFS, this);
-            setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
-        }
-       }
-
        FixPlayermodel(this);
 
        if (this.shootfromfixedorigin != autocvar_g_shootfromfixedorigin) {
@@ -2518,8 +2481,7 @@ void PlayerPreThink (entity this)
                }
                if (!assume_unchanged && autocvar_sv_eventlog)
                        GameLogEcho(strcat(":name:", ftos(this.playerid), ":", playername(this, false)));
-               if (CS(this).netname_previous) strunzone(CS(this).netname_previous);
-               CS(this).netname_previous = strzone(this.netname);
+               strcpy(CS(this).netname_previous, this.netname);
        }
 
        // version nagging
index 48d42da0092d2f8cf059d1f2037e8aace3bbc372..7499ee8ddfac0e0fbbd299ab4de285b53c62ea83 100644 (file)
@@ -231,5 +231,5 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re
 
 bool Spectate(entity this, entity pl);
 
-#define SPECTATE_COPY() [[accumulate]] void SpectateCopy(entity this, entity spectatee)
+#define SPECTATE_COPY() ACCUMULATE void SpectateCopy(entity this, entity spectatee)
 #define SPECTATE_COPYFIELD(fld) SPECTATE_COPY() { this.(fld) = spectatee.(fld); }
index 088925f100f2f3f47499a4be5a72bcac7861bf15..47e94f52034bf8b1a0255c8ca76b419d9772d891 100644 (file)
@@ -614,8 +614,10 @@ void ClientCommand_voice(entity caller, float request, float argc, string comman
                                        sprint(caller, sprintf("Invalid voice. Use one of: %s\n", allvoicesamples));
                                        return;
                                }
-                               if (argc >= 3) VoiceMessage(caller, e, substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2)));
-                               else VoiceMessage(caller, e, "");
+                               string msg = "";
+                               if (argc >= 3)
+                                       msg = substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2));
+                               VoiceMessage(caller, e, msg);
 
                                return;
                        }
index 2f7467eab7bac87ff6191a004bac3c568d4efa70..db822eb71f7ea45e2536677da8f50aab4d071bcf 100644 (file)
@@ -391,7 +391,7 @@ void CommonCommand_editmob(int request, entity caller, int argc)
                                                break;
                                        });
 
-                                       if (!found && arg_lower != "random") { print_to(caller, "Invalid monster"); return; }
+                                       if (!found && arg_lower != "random" && arg_lower != "anyrandom") { print_to(caller, "Invalid monster"); return; }
 
                                        totalspawned += 1;
                                        WarpZone_TraceBox(CENTER_OR_VIEWOFS(caller), caller.mins, caller.maxs, CENTER_OR_VIEWOFS(caller) + v_forward * 150, true, caller);
index 6d037473dd39907726f7eca7615610838f6b4f19..638dbb1565eabf86df69239c58be3c40f77e9516 100644 (file)
@@ -128,19 +128,15 @@ void VoteReset()
 
        if (vote_called)
        {
-               strunzone(vote_called_command);
-               strunzone(vote_called_display);
-               strunzone(vote_caller_name);
+               strfree(vote_called_command);
+               strfree(vote_called_display);
+               strfree(vote_caller_name);
        }
 
        vote_called = VOTE_NULL;
        vote_caller = NULL;
-       vote_caller_name = string_null;
        vote_endtime = 0;
 
-       vote_called_command = string_null;
-       vote_called_display = string_null;
-
        vote_parsed_command = string_null;
        vote_parsed_display = string_null;
 
@@ -660,6 +656,14 @@ int VoteCommand_parse(entity caller, string vote_command, string vote_list, floa
 
        if (!VoteCommand_checkargs(startpos, argc)) return 0;
 
+       switch (MUTATOR_CALLHOOK(VoteCommand_Parse, caller, first_command, vote_command, startpos, argc))
+       {
+               case MUT_VOTEPARSE_CONTINUE: { break; }
+               case MUT_VOTEPARSE_SUCCESS: { return 1; }
+               case MUT_VOTEPARSE_INVALID: { return -1; }
+               case MUT_VOTEPARSE_UNACCEPTABLE: { return 0; }
+       }
+
        switch (first_command) // now go through and parse the proper commands to adjust as needed.
        {
                case "kick":
index f85d6e2b6f22ae53ff521c4e52668c635f5dd5f4..e005d0ca844eca9c9bcbfd0b15db6dd27ad820d2 100644 (file)
@@ -7,7 +7,7 @@
 
 // Globals
 
-float g_footsteps, g_grappling_hook, g_instagib;
+float g_footsteps, g_grappling_hook;
 float g_warmup_allguns;
 float g_warmup_allow_timeout;
 float warmup_stage;
index b5ab77d419e02db58a9ac07cbc744bf998d84999..b36cfc95ac9c4bcf43318ac35d955dc6bb6e90fe 100644 (file)
@@ -779,7 +779,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                        }
                }
 
-               if(!g_instagib)
+               if(!autocvar_g_instagib)
                {
                        // apply strength multiplier
                        if (attacker.items & ITEM_Strength.m_itemid)
index 1026e3aa7a2dfaa6b0a139c3ad75eca12e141f94..c8f85247c8aa775cd3c63d9d3d2c980800db807f 100644 (file)
@@ -8,11 +8,11 @@
 #include "../common/triggers/triggers.qh"
 
 entityclass(BGMScript);
-class(BGMScript) .string bgmscript;
-class(BGMScript) .float bgmscriptattack;
-class(BGMScript) .float bgmscriptdecay;
-class(BGMScript) .float bgmscriptsustain;
-class(BGMScript) .float bgmscriptrelease;
+classfield(BGMScript) .string bgmscript;
+classfield(BGMScript) .float bgmscriptattack;
+classfield(BGMScript) .float bgmscriptdecay;
+classfield(BGMScript) .float bgmscriptsustain;
+classfield(BGMScript) .float bgmscriptrelease;
 
 #include "../common/constants.qh"
 #include "../lib/csqcmodel/sv_model.qh"
index a3bb6eb216e8677b4ae7add94f76dbee46188034..b9c62643163739a9badeb1d2390a458c543c8a28 100644 (file)
@@ -145,12 +145,8 @@ void cvar_changes_init()
        string k, v, d;
        float n, i, adding, pureadding;
 
-       if(cvar_changes)
-               strunzone(cvar_changes);
-       cvar_changes = string_null;
-       if(cvar_purechanges)
-               strunzone(cvar_purechanges);
-       cvar_purechanges = string_null;
+       strfree(cvar_changes);
+       strfree(cvar_purechanges);
        cvar_purechanges_count = 0;
 
        h = buf_create();
@@ -1199,9 +1195,7 @@ void Maplist_Init()
                error("empty maplist, cannot select a new map");
        Map_Current = bound(0, GetMaplistPosition(), Map_Count - 1);
 
-       if(Map_Current_Name)
-               strunzone(Map_Current_Name);
-       Map_Current_Name = strzone(argv(Map_Current)); // will be automatically freed on exit thanks to DP
+       strcpy(Map_Current_Name, argv(Map_Current)); // will be automatically freed on exit thanks to DP
        // this may or may not be correct, but who cares, in the worst case a map
        // isn't chosen in the first pass that should have been
 }
index 98dbf5c55b748d5a4d106f8dadec8fc3e29b412f..cf0eb13b77b7e22a94e598937a24cc5b74b75a59 100644 (file)
@@ -211,12 +211,8 @@ void OnlineBanList_Think(entity this)
        if(argc == 0)
                goto killme;
 
-       if(OnlineBanList_Servers)
-               strunzone(OnlineBanList_Servers);
-       OnlineBanList_Servers = argv(0);
-       for(i = 1; i < argc; ++i)
-               OnlineBanList_Servers = strcat(OnlineBanList_Servers, ";", argv(i));
-       OnlineBanList_Servers = strzone(OnlineBanList_Servers);
+       string s = argv(0); for(i = 1; i < argc; ++i) s = strcat(s, ";", argv(i));
+       strcpy(OnlineBanList_Servers, s);
 
        uri = strcat(     "action=list&hostname=", uri_escape(autocvar_hostname));
        uri = strcat(uri, "&servers=", uri_escape(OnlineBanList_Servers));
index 209ac7af98085daf7bdffed0fc335eacba721141..816945d2ab0bc9bbdcb50ef78f11b6f813a50597 100644 (file)
@@ -109,16 +109,8 @@ void MapVote_UnzoneStrings()
 {
        for(int j = 0; j < mapvote_count; ++j)
        {
-               if ( mapvote_maps[j] )
-               {
-                       strunzone(mapvote_maps[j]);
-                       mapvote_maps[j] = string_null;
-               }
-               if ( mapvote_maps_pakfile[j] )
-               {
-                       strunzone(mapvote_maps_pakfile[j]);
-                       mapvote_maps_pakfile[j] = string_null;
-               }
+               strfree(mapvote_maps[j]);
+               strfree(mapvote_maps_pakfile[j]);
        }
 }
 
index ff762e9046fd51d89046dbb196a258d3ef02acec..bbbefd5a88f11cbb32e959a313366da154c3de74 100644 (file)
@@ -298,17 +298,13 @@ void GetCvars_handleString(entity this, entity store, string thisname, float f,
 {
        if (f < 0)
        {
-               if (store.(field))
-                       strunzone(store.(field));
-               store.(field) = string_null;
+               strfree(store.(field));
        }
        else if (f > 0)
        {
                if (thisname == name)
                {
-                       if (store.(field))
-                               strunzone(store.(field));
-                       store.(field) = strzone(argv(f + 1));
+                       strcpy(store.(field), argv(f + 1));
                }
        }
        else
@@ -323,8 +319,7 @@ void GetCvars_handleString_Fixup(entity this, entity store, string thisname, flo
                        string s = func(this, strcat1(store.(field)));
                        if (s != store.(field))
                        {
-                               strunzone(store.(field));
-                               store.(field) = strzone(s);
+                               strcpy(store.(field), s);
                        }
                }
 }
@@ -366,14 +361,8 @@ void GetCvars_handleFloatOnce(entity this, entity store, string thisname, float
 }
 string W_FixWeaponOrder_ForceComplete_AndBuildImpulseList(entity this, string wo)
 {
-       string o;
-       o = W_FixWeaponOrder_ForceComplete(wo);
-       if(CS(this).weaponorder_byimpulse)
-       {
-               strunzone(CS(this).weaponorder_byimpulse);
-               CS(this).weaponorder_byimpulse = string_null;
-       }
-       CS(this).weaponorder_byimpulse = strzone(W_FixWeaponOrder_BuildImpulseList(o));
+       string o = W_FixWeaponOrder_ForceComplete(wo);
+       strcpy(CS(this).weaponorder_byimpulse, W_FixWeaponOrder_BuildImpulseList(o));
        return o;
 }
 
index 5538a574428cb4b8cbc5dbbe01dec2aa0f5264c8..41e725946a96cb43c1cd5febd0a04f76deb79359 100644 (file)
@@ -222,8 +222,6 @@ void readlevelcvars()
        if(cvar("sv_allow_fullbright"))
                serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
 
-       g_instagib = cvar("g_instagib");
-
        sv_clones = cvar("sv_clones");
        sv_foginterval = cvar("sv_foginterval");
        g_footsteps = cvar("g_footsteps");
index 0d801ec22e2f811c3cc4ecf72cc50933987c83bf..c101be0ccf4b8aa9a53497268e922c3270613192 100644 (file)
@@ -3,7 +3,7 @@
 #include <common/mutators/base.qh>
 
 // register all possible hooks here
+
 // to use a hook, first register your mutator using REGISTER_MUTATOR
 // then create your function using MUTATOR_HOOKFUNCTION
 
@@ -435,6 +435,8 @@ MUTATOR_HOOKABLE(PlayerDamaged, EV_PlayerDamaged);
 #define EV_W_DecreaseAmmo(i, o) \
     /** actor */            i(entity, MUTATOR_ARGV_0_entity) \
     /** weapon entity */    i(entity, MUTATOR_ARGV_1_entity) \
+    /** ammo to take */     i(float, MUTATOR_ARGV_2_float) \
+    /**/                    o(float, MUTATOR_ARGV_2_float) \
     /**/
 MUTATOR_HOOKABLE(W_DecreaseAmmo, EV_W_DecreaseAmmo);
 
@@ -690,6 +692,26 @@ constants for resource types. Return true to forbid the change. */
        /**/
 MUTATOR_HOOKABLE(SetResourceAmount, EV_SetResourceAmount);
 
+/** Called after the amount of resource of an entity has changed. See RESOURCE_*
+constants for resource types. Amount wasted is the amount of resource that is
+above resource limit so it was not given. */
+#define EV_ResourceAmountChanged(i, o) \
+       /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */  i(int, MUTATOR_ARGV_1_int) \
+       /** amount */         i(float, MUTATOR_ARGV_2_float) \
+       /**/
+MUTATOR_HOOKABLE(ResourceAmountChanged, EV_ResourceAmountChanged);
+
+/** Called when there was an attempt to set entity resources higher than their
+limit. See RESOURCE_* constants for resource types. Amount wasted is the amount
+of resource that is above resource limit so it was not given. */
+#define EV_ResourceWasted(i, o) \
+       /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */  i(int, MUTATOR_ARGV_1_int) \
+       /** amount wasted */  i(float, MUTATOR_ARGV_2_float) \
+       /**/
+MUTATOR_HOOKABLE(ResourceWasted, EV_ResourceWasted);
+
 /** Called when entity is being given some resource. See RESOURCE_* constants
 for resource types. Return true to forbid giving. */
 #define EV_GiveResource(i, o) \
@@ -701,6 +723,19 @@ for resource types. Return true to forbid giving. */
        /**/
 MUTATOR_HOOKABLE(GiveResource, EV_GiveResource);
 
+/** Called when entity is being given some resource with specified limit. See
+RESOURCE_* constants for resource types. Return true to forbid giving. */
+#define EV_GiveResourceWithLimit(i, o) \
+       /** receiver */      i(entity, MUTATOR_ARGV_0_entity) \
+       /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+       /**/                 o(int, MUTATOR_ARGV_1_int) \
+       /** amount */        i(float, MUTATOR_ARGV_2_float) \
+       /**/                 o(float, MUTATOR_ARGV_2_float) \
+       /** limit */         i(float, MUTATOR_ARGV_3_float) \
+       /**/                 o(float, MUTATOR_ARGV_3_float) \
+       /**/
+MUTATOR_HOOKABLE(GiveResourceWithLimit, EV_GiveResourceWithLimit);
+
 /** called at when a player connect */
 #define EV_ClientConnect(i, o) \
     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
@@ -1082,3 +1117,20 @@ MUTATOR_HOOKABLE(HavocBot_Aim, EV_HavocBot_Aim);
     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
     /**/
 MUTATOR_HOOKABLE(CalculateRespawnTime, EV_CalculateRespawnTime);
+
+/** called when parsing a vote command. */
+#define EV_VoteCommand_Parse(i, o) \
+    /** caller */                           i(entity, MUTATOR_ARGV_0_entity) \
+    /** first command */                    i(string, MUTATOR_ARGV_1_string) \
+    /** vote command */                     i(string, MUTATOR_ARGV_2_string) \
+    /** start position of vote command */   i(float, MUTATOR_ARGV_3_float) \
+    /** argument count */                   i(float, MUTATOR_ARGV_4_float) \
+    /**/
+MUTATOR_HOOKABLE(VoteCommand_Parse, EV_VoteCommand_Parse);
+
+enum {
+    MUT_VOTEPARSE_CONTINUE, // return this flag to make the function continue as normal
+    MUT_VOTEPARSE_SUCCESS, // return 1 (vote parsed)
+    MUT_VOTEPARSE_INVALID, // return -1 (vote parsed but counted as invalid, no action or vote)
+    MUT_VOTEPARSE_UNACCEPTABLE // return 0 (vote parameter counted as unacceptable, warns caller)
+};
index b34e3f59f51fe58ac3f5cccb5828b68fae45f242..e0d25e9e8f494c829c8fbf3156f15c92f168cddf 100644 (file)
@@ -2249,8 +2249,7 @@ MUTATOR_HOOKFUNCTION(ctf, GetPressedKeys)
                if(player.stored_netname != player.netname)
                {
                        db_put(ServerProgsDB, strcat("/uid2name/", player.crypto_idfp), player.netname);
-                       strunzone(player.stored_netname);
-                       player.stored_netname = strzone(player.netname);
+                       strcpy(player.stored_netname, player.netname);
                }
        }
 }
index daaf8a969592e810af3531a1cdcded327b46a8fc..1363411aa9e75c7f388aad0439b6e7ef1abc2371 100644 (file)
@@ -286,8 +286,7 @@ MUTATOR_HOOKFUNCTION(cts, GetPressedKeys)
                if(player.stored_netname != player.netname)
                {
                        db_put(ServerProgsDB, strcat("/uid2name/", player.crypto_idfp), player.netname);
-                       strunzone(player.stored_netname);
-                       player.stored_netname = strzone(player.netname);
+                       strcpy(player.stored_netname, player.netname);
                }
        }
 
index aa6d12a83e063166da288364d0314e521d3c9970..e4109b72a8523e84bd913951409a50339866ed50 100644 (file)
@@ -325,8 +325,7 @@ MUTATOR_HOOKFUNCTION(rc, GetPressedKeys)
                if(player.stored_netname != player.netname)
                {
                        db_put(ServerProgsDB, strcat("/uid2name/", player.crypto_idfp), player.netname);
-                       strunzone(player.stored_netname);
-                       player.stored_netname = strzone(player.netname);
+                       strcpy(player.stored_netname, player.netname);
                }
        }
 
index 8804063dc6e5c918cb64e1b2912c2a27e99b8771..743d02d03c0acc1af8d95a94c460131e6a398f94 100644 (file)
@@ -316,9 +316,7 @@ void race_setTime(string map, float t, string myuid, string mynetname, entity e,
        }
 
        race_SendRankings(newpos, player_prevpos, 0, MSG_ALL);
-       if(rankings_reply)
-               strunzone(rankings_reply);
-       rankings_reply = strzone(getrankings());
+       strcpy(rankings_reply, getrankings());
 
        if(newpos == player_prevpos)
        {
@@ -366,9 +364,7 @@ void race_deleteTime(string map, float pos)
        if(pos == 1)
                race_send_recordtime(MSG_ALL);
 
-       if(rankings_reply)
-               strunzone(rankings_reply);
-       rankings_reply = strzone(getrankings());
+       strcpy(rankings_reply, getrankings());
 }
 
 void race_SendTime(entity e, float cp, float t, float tvalid)
@@ -442,9 +438,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                if(t < recordtime || recordtime == 0)
                                {
                                        race_checkpoint_records[cp] = t;
-                                       if(race_checkpoint_recordholders[cp])
-                                               strunzone(race_checkpoint_recordholders[cp]);
-                                       race_checkpoint_recordholders[cp] = strzone(e.netname);
+                                       strcpy(race_checkpoint_recordholders[cp], e.netname);
                                        if(g_race_qualifying)
                                                FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.race_checkpoint == cp, { race_SendNextCheckpoint(it, 0); });
                                }
@@ -1089,9 +1083,7 @@ void race_ClearRecords()
        for(int j = 0; j < MAX_CHECKPOINTS; ++j)
        {
                race_checkpoint_records[j] = 0;
-               if(race_checkpoint_recordholders[j])
-                       strunzone(race_checkpoint_recordholders[j]);
-               race_checkpoint_recordholders[j] = string_null;
+               strfree(race_checkpoint_recordholders[j]);
        }
 
        FOREACH_CLIENT(true, {
index a2a1358b97856196366b7dc95c909c620f2152ec..4ad66bb98ed2169380e7074ea23147a503e652cf 100644 (file)
@@ -83,17 +83,24 @@ void SetResourceAmount(entity e, int resource_type, float amount)
        }
        resource_type = M_ARGV(1, int);
        amount = M_ARGV(2, float);
-       .float resource_field = GetResourceField(resource_type);
-       if (e.(resource_field) == amount)
-       {
-               return;
-       }
        float max_amount = GetResourceLimit(e, resource_type);
+       float amount_wasted = 0;
        if (amount > max_amount)
        {
+               amount_wasted = amount - max_amount;
                amount = max_amount;
        }
-       e.(resource_field) = amount;
+       .float resource_field = GetResourceField(resource_type);
+       if (e.(resource_field) != amount)
+       {
+               e.(resource_field) = amount;
+               MUTATOR_CALLHOOK(ResourceAmountChanged, e, resource_type, amount);
+       }
+       if (amount_wasted == 0)
+       {
+               return;
+       }
+       MUTATOR_CALLHOOK(ResourceWasted, e, resource_type, amount_wasted);
 }
 
 void GiveResource(entity receiver, int resource_type, float amount)
@@ -144,6 +151,19 @@ void GiveResource(entity receiver, int resource_type, float amount)
 void GiveResourceWithLimit(entity receiver, int resource_type, float amount,
        float limit)
 {
+       if (amount == 0)
+       {
+               return;
+       }
+       bool forbid = MUTATOR_CALLHOOK(GiveResourceWithLimit, receiver,
+               resource_type, amount, limit);
+       if (forbid)
+       {
+               return;
+       }
+       resource_type = M_ARGV(1, int);
+       amount = M_ARGV(2, float);
+       limit = M_ARGV(3, float);
        if (amount == 0)
        {
                return;
index 3f1db42903ddd010c209febba24f608cba1c1840..67c115c8a56ff7dfc2135e973c693f6476762efa 100644 (file)
@@ -535,9 +535,7 @@ void WinningConditionHelper(entity this)
                }
        }
 
-       if(worldstatus)
-               strunzone(worldstatus);
-       worldstatus = strzone(s);
+       strcpy(worldstatus, s);
 
        FOREACH_CLIENT(true, {
                string s = "";
@@ -556,9 +554,7 @@ void WinningConditionHelper(entity this)
                                s = "-666";
                }
 
-               if(it.clientstatus)
-                       strunzone(it.clientstatus);
-               it.clientstatus = strzone(s);
+               strcpy(it.clientstatus, s);
        });
 }
 
index 1130b6a4e5dd349abdf935a81039e0334c22c443..487ab1fc533821590ab49c18fdeffb7cf24dd686 100644 (file)
@@ -360,7 +360,7 @@ void SV_OnEntityPreSpawnFunction(entity this)
        }
        return;
 LABEL(cleanup)
-    builtin_remove(this);
+    delete(this);
 }
 
 void WarpZone_PostInitialize_Callback()
index cf21de4bfd3978ac2942e03eb0e7ccafa6234318..43aa4a26bd24e61d362d64dce55f33090ee88c9a 100644 (file)
@@ -131,12 +131,8 @@ string getwelcomemessage(entity this)
 
        if(cache_lastmutatormsg != autocvar_g_mutatormsg)
        {
-               if(cache_lastmutatormsg)
-                       strunzone(cache_lastmutatormsg);
-               if(cache_mutatormsg)
-                       strunzone(cache_mutatormsg);
-               cache_lastmutatormsg = strzone(autocvar_g_mutatormsg);
-               cache_mutatormsg = strzone(cache_lastmutatormsg);
+               strcpy(cache_lastmutatormsg, autocvar_g_mutatormsg);
+               strcpy(cache_mutatormsg, cache_lastmutatormsg);
        }
 
        if (cache_mutatormsg != "") {
index f9cae87a3639b8eabb85154f92ea9cabf5d97508..8bfcbb79cfb37d58734f12493f2e3f922d844ea7 100644 (file)
@@ -660,9 +660,11 @@ void W_AttachToShotorg(entity actor, .entity weaponentity, entity flash, vector
 
 void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use, .entity weaponentity)
 {
-       if (MUTATOR_CALLHOOK(W_DecreaseAmmo, actor, actor.(weaponentity))) return;
+       if (MUTATOR_CALLHOOK(W_DecreaseAmmo, actor, actor.(weaponentity), ammo_use)) return;
        if ((actor.items & IT_UNLIMITED_WEAPON_AMMO) && !wep.reloading_ammo) return;
 
+       ammo_use = M_ARGV(2, float);
+
        entity w_ent = actor.(weaponentity);
 
        // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
@@ -741,8 +743,7 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen
        this.reload_ammo_min = sent_ammo_min;
        this.reload_ammo_amount = e.reloading_ammo;
        this.reload_time = e.reloading_time;
-       if (actor.reload_sound) strunzone(actor.reload_sound);
-       actor.reload_sound = strzone(Sound_fixpath(sent_sound));
+       strcpy(actor.reload_sound, Sound_fixpath(sent_sound));
 
        // don't reload weapons that don't have the RELOADABLE flag
        if (!(e.spawnflags & WEP_FLAG_RELOADABLE))
diff --git a/ruleset-nexuiz.cfg b/ruleset-nexuiz.cfg
new file mode 100644 (file)
index 0000000..7441942
--- /dev/null
@@ -0,0 +1,11 @@
+exec xonotic-server.cfg
+
+exec balance-nexuiz25.cfg
+exec physicsNexuiz26.cfg
+
+sv_gameplayfix_delayprojectiles 1
+
+// new toys to restore the weapons
+g_new_toys 1
+g_new_toys_autoreplace 0
+g_new_toys_use_pickupsound 0
index 29d5c2f6754b51442d06df46def79bf1ad2e04e2..a6ecd64dca1afc17c763e14f4a02d9e70c4f49ff 100644 (file)
@@ -170,6 +170,7 @@ set bot_ai_timeitems_minrespawndelay 25 "bots run to items with this minimum res
 set g_waypointeditor 0
 set g_waypointeditor_auto 0 "Automatically create waypoints for bots while playing; BEWARE, this currently creates too many of them"
 set g_waypointeditor_symmetrical 0 "Enable symmetrical editing of waypoints on symmetrical CTF maps (NOTE: it assumes that the map is perfectly symmetrical). 1: automatically determine origin of symmetry; -1: use custom origin (g_waypointeditor_symmetrical_origin); 2: automatically determine axis of symmetry; -2: use custom axis (g_waypointeditor_symmetrical_axis)"
+set g_waypointeditor_symmetrical_allowload 1 "Allow loading symmetry settings from waypoint files into g_waypointeditor_symmetrical* cvars on map start"
 set g_waypointeditor_symmetrical_origin "0 0" "Custom origin of symmetry (x y)"
 set g_waypointeditor_symmetrical_order 0 "if >= 2 apply rotational symmetry (around origin of symmetry) of this order, otherwise apply autodetected order of symmetry"
 set g_waypointeditor_symmetrical_axis "0 0" "Custom axis of symmetry (m q parameters of y = mx + q)"
@@ -179,7 +180,7 @@ set bot_vs_human 0  "Bots and humans play in different teams when set. positive v
 
 set g_spawnshieldtime 1 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
 set g_spawnshield_blockdamage 1 "how much spawn shield protects you from damage (1 = full protection)"
-set g_antilag 2        "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past, 3 = unverified client side hit scan)"
+set g_antilag 2        "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past)"
 set g_antilag_nudge 0 "don't touch"
 set g_shootfromeye 0 "shots are fired from your eye/crosshair; visual gun position can still be influenced by cl_gunalign 1 and 2"
 set g_shootfromcenter 0 "weapon gets moved to the center, shots still come from the barrel of your weapon; visual gun position can still be influenced by cl_gunalign 1 and 2"