]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'martin-t/bullet-trails' into 'master'
authorMario <zacjardine@y7mail.com>
Sun, 30 Sep 2018 14:36:44 +0000 (14:36 +0000)
committerMario <zacjardine@y7mail.com>
Sun, 30 Sep 2018 14:36:44 +0000 (14:36 +0000)
Pass effect entity to fireBullet(), give weak trail to hitscan weaps

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

21 files changed:
.gitlab-ci.yml
gamemodes-client.cfg
gamemodes-server.cfg
qcsrc/client/csqcmodel_hooks.qc
qcsrc/common/gamemodes/gamemode/_mod.inc
qcsrc/common/gamemodes/gamemode/_mod.qh
qcsrc/common/gamemodes/gamemode/duel/_mod.inc [new file with mode: 0644]
qcsrc/common/gamemodes/gamemode/duel/_mod.qh [new file with mode: 0644]
qcsrc/common/gamemodes/gamemode/duel/sv_duel.qc [new file with mode: 0644]
qcsrc/common/gamemodes/gamemode/duel/sv_duel.qh [new file with mode: 0644]
qcsrc/common/mapinfo.qh
qcsrc/common/playerstats.qc
qcsrc/common/weapons/weapon/arc.qc
qcsrc/menu/xonotic/util.qc
qcsrc/server/bot/default/bot.qc
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/compat/quake3.qc
qcsrc/server/g_world.qc
qcsrc/server/mutators/events.qh
qcsrc/server/weapons/weaponsystem.qc

index f960751ca51d8b790ce2efefcea7944912998478..0ad802d838e4d7603b3ff29a46eb202265ac9cd0 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=e62d1a2375f0976ab12e2d980add29bd
+    - EXPECT=14643a645a99b8f855a6af279569d2a1
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index e7a1607f15c8274f10603d441f65f9be21a3133d..c43b9d1d3f2e6fe73fddbb33e8489670350edc4d 100644 (file)
@@ -31,6 +31,7 @@ alias cl_hook_gamestart_cts
 alias cl_hook_gamestart_ka
 alias cl_hook_gamestart_ft
 alias cl_hook_gamestart_inv
+alias cl_hook_gamestart_duel
 alias cl_hook_gameend "rpn /cl_matchcount dup load 1 + =" // increase match count every time a game ends
 alias cl_hook_shutdown
 alias cl_hook_activeweapon
index 5a9ec457b5ca6613dc617929d0e0c69f290ff825..7cc47c3639858e77f0aea47961a61ecd86bd5378 100644 (file)
@@ -28,6 +28,7 @@ alias sv_hook_gamestart_cts
 alias sv_hook_gamestart_ka
 alias sv_hook_gamestart_ft
 alias sv_hook_gamestart_inv
+alias sv_hook_gamestart_duel
 alias sv_hook_gamerestart
 alias sv_hook_gameend
 
@@ -54,16 +55,17 @@ alias sv_vote_gametype_hook_nb
 alias sv_vote_gametype_hook_ons
 alias sv_vote_gametype_hook_rc
 alias sv_vote_gametype_hook_tdm
+alias sv_vote_gametype_hook_duel
 
-// Example preset to allow duel to be used for the gametype voting screen
+// Example preset to allow 1v1ctf to be used for the gametype voting screen
 // sv_vote_gametype_*_type Must be set to the name of the gametype the option is based on
 // sv_vote_gametype_*_name Contains a human-readable name of the gametype
 // sv_vote_gametype_*_description Contains a longer description
-//set sv_vote_gametype_duel_type dm
-//set sv_vote_gametype_duel_name Duel
-//set sv_vote_gametype_duel_description "One vs One match"
+//set sv_vote_gametype_1v1ctf_type ctf
+//set sv_vote_gametype_1v1ctf_name "Capture the Flag Duel"
+//set sv_vote_gametype_1v1ctf_description "One vs One match in CTF"
 //alias sv_vote_gametype_hook_all "set g_maxplayers 0"
-//alias sv_vote_gametype_hook_duel "set g_maxplayers 2"
+//alias sv_vote_gametype_hook_1v1ctf "set g_maxplayers 2"
 
 
 // ===========
@@ -196,6 +198,13 @@ set g_inv_respawn_delay_large_count 0
 set g_inv_respawn_delay_max 0
 set g_inv_respawn_waves 0
 set g_inv_weapon_stay 0
+set g_duel_respawn_delay_small 0
+set g_duel_respawn_delay_small_count 0
+set g_duel_respawn_delay_large 0
+set g_duel_respawn_delay_large_count 0
+set g_duel_respawn_delay_max 0
+set g_duel_respawn_waves 0
+set g_duel_weapon_stay 0
 
 
 // =========
@@ -525,3 +534,8 @@ set g_invasion_spawnpoint_spawn_delay 0.5
 set g_invasion_teams 0 "number of teams in invasion (note: use mapinfo to set this)"
 set g_invasion_team_spawns 1 "use team spawns in teamplay invasion mode"
 set g_invasion_type 0 "type of invasion mode - 0: round-based, 1: hunting, 2: complete the stage (note: use mapinfo to set this)"
+
+// ======
+//  duel
+// ======
+set g_duel 0 "Duel: frag the opponent more in a one versus one arena battle"
index 035ba2a1647c29a2445ca54d73022670536cfed3..522859c8b193ea1d4c4729b72ba50d6322aafc5c 100644 (file)
@@ -600,7 +600,7 @@ void CSQCModel_Hook_PreDraw(entity this, bool isplayer)
                return;
        this.csqcmodel_predraw_run = framecount;
 
-       if(!this.modelindex || this.model == "null")
+       if(!this.modelindex || this.model == "null" || this.alpha < 0)
        {
                this.drawmask = 0;
                return;
@@ -608,7 +608,7 @@ void CSQCModel_Hook_PreDraw(entity this, bool isplayer)
        else
                this.drawmask = MASK_NORMAL;
 
-       if(this.isplayermodel) // this checks if it's a player MODEL!
+       if(this.isplayermodel && this.drawmask) // this checks if it's a player MODEL!
        {
                CSQCPlayer_ModelAppearance_Apply(this, this.entnum == player_localnum + 1);
                CSQCPlayer_LOD_Apply(this);
index c4cd002c782221fe420d38415c25fed570909a4d..a33ec87a01a34a5a8406f57aa3c3d52829cf3994 100644 (file)
@@ -6,6 +6,7 @@
 #include <common/gamemodes/gamemode/cts/_mod.inc>
 #include <common/gamemodes/gamemode/deathmatch/_mod.inc>
 #include <common/gamemodes/gamemode/domination/_mod.inc>
+#include <common/gamemodes/gamemode/duel/_mod.inc>
 #include <common/gamemodes/gamemode/freezetag/_mod.inc>
 #include <common/gamemodes/gamemode/invasion/_mod.inc>
 #include <common/gamemodes/gamemode/keepaway/_mod.inc>
index d7c1aa66cc35f6f3f8143031123542abf134a33c..ffd71d59d3f1092453b6d83f8048003693dfa531 100644 (file)
@@ -6,6 +6,7 @@
 #include <common/gamemodes/gamemode/cts/_mod.qh>
 #include <common/gamemodes/gamemode/deathmatch/_mod.qh>
 #include <common/gamemodes/gamemode/domination/_mod.qh>
+#include <common/gamemodes/gamemode/duel/_mod.qh>
 #include <common/gamemodes/gamemode/freezetag/_mod.qh>
 #include <common/gamemodes/gamemode/invasion/_mod.qh>
 #include <common/gamemodes/gamemode/keepaway/_mod.qh>
diff --git a/qcsrc/common/gamemodes/gamemode/duel/_mod.inc b/qcsrc/common/gamemodes/gamemode/duel/_mod.inc
new file mode 100644 (file)
index 0000000..5925816
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef SVQC
+    #include <common/gamemodes/gamemode/duel/sv_duel.qc>
+#endif
diff --git a/qcsrc/common/gamemodes/gamemode/duel/_mod.qh b/qcsrc/common/gamemodes/gamemode/duel/_mod.qh
new file mode 100644 (file)
index 0000000..00e553c
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef SVQC
+    #include <common/gamemodes/gamemode/duel/sv_duel.qh>
+#endif
diff --git a/qcsrc/common/gamemodes/gamemode/duel/sv_duel.qc b/qcsrc/common/gamemodes/gamemode/duel/sv_duel.qc
new file mode 100644 (file)
index 0000000..7e4c891
--- /dev/null
@@ -0,0 +1,18 @@
+#include "sv_duel.qh"
+
+MUTATOR_HOOKFUNCTION(duel, ReadLevelCvars)
+{
+       warmup_stage = 1;
+       //sv_ready_restart_after_countdown = 0;
+}
+
+MUTATOR_HOOKFUNCTION(duel, GetPlayerLimit)
+{
+       M_ARGV(0, int) = 2; // duel is always 1v1!
+}
+
+MUTATOR_HOOKFUNCTION(duel, Scores_CountFragsRemaining)
+{
+       // announce remaining frags?
+       return true;
+}
diff --git a/qcsrc/common/gamemodes/gamemode/duel/sv_duel.qh b/qcsrc/common/gamemodes/gamemode/duel/sv_duel.qh
new file mode 100644 (file)
index 0000000..9a0d716
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <common/mutators/base.qh>
+REGISTER_MUTATOR(duel, false)
+{
+    MUTATOR_STATIC();
+       return 0;
+}
index 63723afd7ab2deb70023f05a2762d108d082f9c8..4ece9215609bf05fb0b6fd4cce295bc58512351b 100644 (file)
@@ -494,6 +494,27 @@ CLASS(Invasion, Gametype)
 ENDCLASS(Invasion)
 REGISTER_GAMETYPE(INVASION, NEW(Invasion));
 
+CLASS(Duel, Gametype)
+    INIT(Duel)
+    {
+        this.gametype_init(this, _("Duel"),"duel","g_duel",false,"","timelimit=10 pointlimit=0 leadlimit=0",_("Fight in a one versus one arena battle to decide the winner"));
+    }
+    METHOD(Duel, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+    {
+        return (diameter < 16384);
+    }
+    METHOD(Duel, m_isForcedSupported, bool(Gametype this))
+    {
+        // force all DM maps to work in duel?!
+        // TODO: we should really check the size of maps, some DM maps do not work for duel!
+        if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags))
+            return true;
+        return false;
+    }
+ENDCLASS(Duel)
+REGISTER_GAMETYPE(DUEL, NEW(Duel));
+#define g_duel IS_GAMETYPE(DUEL)
+
 const int MAPINFO_FEATURE_WEAPONS       = 1; // not defined for instagib-only maps
 const int MAPINFO_FEATURE_VEHICLES      = 2;
 const int MAPINFO_FEATURE_TURRETS       = 4;
index 869af4da96533bb90f31f382b35ef0b3ac243a43..2c9bbcde805eb9770015c385877971563b872731 100644 (file)
@@ -258,6 +258,7 @@ void PlayerStats_GameReport_Init() // initiated before InitGameplayMode so that
 }
 
 // this... is a hack, a temporary one until we get a proper duel gametype
+// TODO: remove duel hack after servers have migrated to the proper duel gametype!
 string PlayerStats_GetGametype()
 {
        if(IS_GAMETYPE(DEATHMATCH) && autocvar_g_maxplayers == 2)
index 56a48f2f3114c711acd24a612bbdec7e4971178b..b2847592690092900aa4c4a8a967605f7c08911a 100644 (file)
@@ -265,14 +265,14 @@ void W_Arc_Beam_Think(entity this)
 
        W_SetupShot_Range(
                own,
-               weaponentity, // TODO
+               weaponentity,
                true,
                0,
                SND_Null,
                0,
                WEP_CVAR(arc, beam_damage) * coefficient,
                WEP_CVAR(arc, beam_range),
-               WEP_ARC.m_id
+               thiswep.m_id
        );
 
        // After teleport, "lock" the beam until the teleport is confirmed.
@@ -542,7 +542,7 @@ void W_Arc_Beam(float burst, entity actor, .entity weaponentity)
 void Arc_Smoke(entity actor, .entity weaponentity)
 {
        makevectors(actor.v_angle);
-       W_SetupShot_Range(actor,weaponentity,true,0,SND_Null,0,0,0,WEP_ARC.m_id); // TODO: probably doesn't need deathtype, since this is just a prefire effect
+       W_SetupShot_Range(actor,weaponentity,false,0,SND_Null,0,0,0,WEP_ARC.m_id); // TODO: probably doesn't need deathtype, since this is just a prefire effect
 
        vector smoke_origin = w_shotorg + actor.velocity*frametime;
        if ( actor.arc_overheat > time )
index fb4bb92a80b5421e80d65ef05d2cd178c04ef6e7..e994491121a8ae1bf012f6981d7c8fdbc1a7a465 100644 (file)
@@ -689,6 +689,7 @@ float updateCompression()
        GAMETYPE(MAPINFO_TYPE_NEXBALL) \
        GAMETYPE(MAPINFO_TYPE_ONSLAUGHT) \
        GAMETYPE(MAPINFO_TYPE_ASSAULT) \
+       /* GAMETYPE(MAPINFO_TYPE_DUEL) */ \
        /* GAMETYPE(MAPINFO_TYPE_INVASION) */ \
        /**/
 
index 12e93821f1479246c306490ceb4ec0dfdce9a3d4..0c4668f2f38d3c05eeb5b24e3ff8d44cb861d753 100644 (file)
@@ -607,8 +607,9 @@ float bot_fixcount()
                // add bots to reach minplayers if needed
                bots = max(minbots, minplayers - activerealplayers);
                // cap bots to the max players allowed by the server
-               if(autocvar_g_maxplayers)
-                       bots = min(bots, autocvar_g_maxplayers - activerealplayers);
+               int player_limit = GetPlayerLimit();
+               if(player_limit)
+                       bots = min(bots, player_limit - activerealplayers);
                bots = min(bots, maxclients - realplayers);
 
                if(bots > minbots)
index 7f8862fdf9cc8015e5cf1267b94b894d23888f04..a8d091e86ed8d4333e8af068005baeda35f9f699 100644 (file)
@@ -1916,6 +1916,14 @@ void Join(entity this)
        this.team_selected = false;
 }
 
+int GetPlayerLimit()
+{
+       int player_limit = autocvar_g_maxplayers;
+       MUTATOR_CALLHOOK(GetPlayerLimit, player_limit);
+       player_limit = M_ARGV(0, int);
+       return player_limit;
+}
+
 /**
  * Determines whether the player is allowed to join. This depends on cvar
  * g_maxplayers, if it isn't used this function always return true, otherwise
@@ -1948,11 +1956,13 @@ int nJoinAllowed(entity this, entity ignore)
                        ++currentlyPlaying;
        });
 
+       int player_limit = GetPlayerLimit();
+
        float free_slots = 0;
-       if (!autocvar_g_maxplayers)
+       if (!player_limit)
                free_slots = maxclients - totalClients;
-       else if(currentlyPlaying < autocvar_g_maxplayers)
-               free_slots = min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying);
+       else if(currentlyPlaying < player_limit)
+               free_slots = min(maxclients - totalClients, player_limit - currentlyPlaying);
 
        static float join_prevent_msg_time = 0;
        if(this && ignore && !free_slots && time > join_prevent_msg_time)
index 80965de759808a0fb8b9c0fe190532b4b4d10ef2..605b78ff913b38b13aeb55dfe42cfbdb48b14762 100644 (file)
@@ -277,6 +277,8 @@ void FixPlayermodel(entity player);
 
 void ClientInit_misc(entity this);
 
+int GetPlayerLimit();
+
 bool joinAllowed(entity this);
 void Join(entity this);
 
index 4f5c242c09aa5847f3be769a783af174e3796afa..65f231374f56a8053f23a2c2cce49f98df729c15 100644 (file)
@@ -265,6 +265,8 @@ bool DoesQ3ARemoveThisEntity(entity this)
                        gametypename = "team";
                if(g_ctf)
                        gametypename = "ctf";
+               if(g_duel)
+                       gametypename = "tournament";
                if(maxclients == 1)
                        gametypename = "single";
                // we do not have the other types (oneflag, obelisk, harvester, teamtournament)
index 28aa46cc43ddfa4c9de5f80fc2fb1ddbeca28dc5..522f4f041cc49af4810c0f53fb2070f30c4e75e4 100644 (file)
@@ -265,6 +265,7 @@ void cvar_changes_init()
                BADCVAR("g_dm");
                BADCVAR("g_domination");
                BADCVAR("g_domination_default_teams");
+               BADCVAR("g_duel");
                BADCVAR("g_freezetag");
                BADCVAR("g_freezetag_teams");
                BADCVAR("g_invasion_teams");
index 58e9ca127dabb4fb3183616f7815885fcfafa861..864623bbae4b888f5c3ca4e56e40d70b0d513246 100644 (file)
@@ -1203,3 +1203,12 @@ MUTATOR_HOOKABLE(Freeze, EV_Freeze);
     /** targ */             i(entity, MUTATOR_ARGV_0_entity) \
     /**/
 MUTATOR_HOOKABLE(Unfreeze, EV_Unfreeze);
+
+/**
+ * Called when a player is trying to join, argument is the number of players allowed to join the match
+ */
+#define EV_GetPlayerLimit(i, o) \
+    /** g_maxplayers */             i(int, MUTATOR_ARGV_0_int) \
+    /**/                            o(int, MUTATOR_ARGV_0_int) \
+    /**/
+MUTATOR_HOOKABLE(GetPlayerLimit, EV_GetPlayerLimit);
index d9155c2237b5b8f2e8d5582c6dc88e7834e906ce..2156c89b4a3e1ad21e4ab201c2f16345b44d4268 100644 (file)
@@ -5,6 +5,7 @@
 #include "../command/common.qh"
 #include <server/mutators/_mod.qh>
 #include "../round_handler.qh"
+#include <server/cheats.qh>
 #include <server/resources.qh>
 #include <common/t_items.qh>
 #include <common/animdecide.qh>