Merge branch 'master' into Mario/wepent_experimental
authorMario <mario@smbclan.net>
Wed, 12 Oct 2016 22:53:23 +0000 (08:53 +1000)
committerMario <mario@smbclan.net>
Wed, 12 Oct 2016 22:53:23 +0000 (08:53 +1000)
# Conflicts:
# qcsrc/common/mutators/mutator/overkill/sv_overkill.qc

18 files changed:
.gitlab-ci.yml
defaultXonotic.cfg
gfx/menu/luma/icon_mod_jeff.tga [new file with mode: 0644]
gfx/menu/luminos/icon_mod_jeff.tga [new file with mode: 0644]
gfx/menu/wickedx/icon_mod_jeff.tga [new file with mode: 0644]
gfx/menu/xaw/icon_mod_jeff.tga [new file with mode: 0644]
mutators.cfg
qcsrc/common/mutators/mutator/instagib/sv_instagib.qc
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/physics/movetypes/movetypes.qh
qcsrc/common/physics/player.qc
qcsrc/common/physics/player.qh
qcsrc/common/stats.qh
qcsrc/common/triggers/func/breakable.qc
qcsrc/ecs/systems/physics.qc
qcsrc/server/client.qc
qcsrc/server/g_world.qc
qcsrc/server/mutators/events.qh

index 1a6600e6a3f3ee4c3399dd766b2388e5b360f3d1..7d5bb7b4930b3dd733427db7a9f8b7d674477bb2 100644 (file)
@@ -30,7 +30,7 @@ test_sv_game:
     - wget -O data/maps/g-23.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.cache
     - wget -O data/maps/g-23.waypoints.hardwired https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.hardwired
     - make
-    - EXPECT=1c8499e781ac75ad9872a2dd04573d16
+    - EXPECT=3134955e1b2af87635ba19947dccc2a4
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index 31112ee73aa36636bf6e7dd946407da94ba6380e..8eaf852e7f7318864ddebdc7cfcdccb76ec358fe 100644 (file)
@@ -289,6 +289,8 @@ set sv_gibhealth 100 "Minus health a dead body must have in order to get gibbed"
 set sv_friction_on_land 0
 set sv_friction_slick 0.5
 
+set sv_slick_applygravity 0
+
 set sv_aircontrol_backwards 0 "apply forward aircontrol options to backward movement"
 
 set sv_player_viewoffset "0 0 35" "view offset of the player model"
@@ -892,7 +894,7 @@ seta menu_slist_categories_CAT_FAVORITED_override ""
 seta menu_slist_categories_CAT_RECOMMENDED_override ""
 seta menu_slist_categories_CAT_NORMAL_override ""
 seta menu_slist_categories_CAT_SERVERS_override "CAT_NORMAL"
-seta menu_slist_categories_CAT_XPM_override "CAT_NORMAL"
+seta menu_slist_categories_CAT_XPM_override ""
 seta menu_slist_categories_CAT_MODIFIED_override ""
 seta menu_slist_categories_CAT_OVERKILL_override ""
 seta menu_slist_categories_CAT_INSTAGIB_override ""
diff --git a/gfx/menu/luma/icon_mod_jeff.tga b/gfx/menu/luma/icon_mod_jeff.tga
new file mode 100644 (file)
index 0000000..ba3080a
Binary files /dev/null and b/gfx/menu/luma/icon_mod_jeff.tga differ
diff --git a/gfx/menu/luminos/icon_mod_jeff.tga b/gfx/menu/luminos/icon_mod_jeff.tga
new file mode 100644 (file)
index 0000000..4bf904b
Binary files /dev/null and b/gfx/menu/luminos/icon_mod_jeff.tga differ
diff --git a/gfx/menu/wickedx/icon_mod_jeff.tga b/gfx/menu/wickedx/icon_mod_jeff.tga
new file mode 100644 (file)
index 0000000..4bf904b
Binary files /dev/null and b/gfx/menu/wickedx/icon_mod_jeff.tga differ
diff --git a/gfx/menu/xaw/icon_mod_jeff.tga b/gfx/menu/xaw/icon_mod_jeff.tga
new file mode 100644 (file)
index 0000000..4bf904b
Binary files /dev/null and b/gfx/menu/xaw/icon_mod_jeff.tga differ
index 18ed08cec71ab2dd9018df48d944eaf63c8b95cb..4b8f1a2376ce25874e880eebba7340762a64f93c 100644 (file)
@@ -31,6 +31,10 @@ set g_instagib 0 "enable instagib"
 set g_instagib_extralives 1 "how many extra lives you will get per powerup"
 set g_instagib_ammo_start 10 "starting ammo"
 set g_instagib_ammo_drop 5 "how much ammo you'll get for weapons or cells"
+set g_instagib_ammo_convert_bullets 0 "convert bullet ammo packs to insta cell ammo packs"
+set g_instagib_ammo_convert_cells 0 "convert normal cell ammo packs to insta cell ammo packs"
+set g_instagib_ammo_convert_rockets 0 "convert rocket ammo packs to insta cell ammo packs"
+set g_instagib_ammo_convert_shells 0 "convert shell ammo packs to insta cell ammo packs"
 set g_instagib_invis_alpha 0.15
 set g_instagib_speed_highspeed 1.5 "speed-multiplier that applies while you carry the invincibility powerup"
 set g_instagib_damagedbycontents 1 "allow damage from lava pits in instagib"
@@ -45,10 +49,11 @@ set g_instagib_friendlypush 1 "allow pushing teammates with the vaporizer primar
 // ==========
 set g_overkill 0 "enable overkill"
 
-set g_overkill_100a_anyway 1
-set g_overkill_100h_anyway 1
 set g_overkill_powerups_replace 1
-set g_overkill_superguns_respawn_time 120
+set g_overkill_filter_healthmega 0
+set g_overkill_filter_armormedium 0
+set g_overkill_filter_armorbig 0
+set g_overkill_filter_armorlarge 0
 
 
 // =========
index 0cf3ed978134babe2cc6135d237e3b3b197e934f..6135e72b556a1aa3d7934fdbc4d631b161981df4 100644 (file)
@@ -1,6 +1,10 @@
 #include "sv_instagib.qh"
 
 int autocvar_g_instagib_ammo_drop;
+bool autocvar_g_instagib_ammo_convert_cells;
+bool autocvar_g_instagib_ammo_convert_rockets;
+bool autocvar_g_instagib_ammo_convert_shells;
+bool autocvar_g_instagib_ammo_convert_bullets;
 int autocvar_g_instagib_extralives;
 float autocvar_g_instagib_speed_highspeed;
 
@@ -356,12 +360,53 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, SetStartItems)
        start_items |= IT_UNLIMITED_SUPERWEAPONS;
 }
 
+void replace_with_insta_cells(entity item)
+{
+       entity e = spawn();
+       setorigin(e, item.origin);
+       e.noalign = item.noalign;
+       e.cnt = item.cnt;
+       e.team = item.team;
+       e.spawnfunc_checked = true;
+       spawnfunc_item_minst_cells(e);
+}
+
 MUTATOR_HOOKFUNCTION(mutator_instagib, FilterItem)
 {
        entity item = M_ARGV(0, entity);
 
        if(item.classname == "item_cells")
-               return true; // no normal cells?
+       {
+               if(autocvar_g_instagib_ammo_convert_cells)
+               {
+                       replace_with_insta_cells(item);
+               }
+               return true;
+       }
+       else if(item.classname == "item_rockets")
+       {
+               if(autocvar_g_instagib_ammo_convert_rockets)
+               {
+                       replace_with_insta_cells(item);
+               }
+               return true;
+       }
+       else if(item.classname == "item_shells")
+       {
+               if(autocvar_g_instagib_ammo_convert_shells)
+               {
+                       replace_with_insta_cells(item);
+               }
+               return true;
+       }
+       else if(item.classname == "item_bullets")
+       {
+               if(autocvar_g_instagib_ammo_convert_bullets)
+               {
+                       replace_with_insta_cells(item);
+               }
+               return true;
+       }
 
        if(item.weapon == WEP_VAPORIZER.m_id && item.classname == "droppedweapon")
        {
@@ -371,13 +416,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, FilterItem)
 
        if(item.weapon == WEP_DEVASTATOR.m_id || item.weapon == WEP_VORTEX.m_id)
        {
-               entity e = spawn();
-               setorigin(e, item.origin);
-               e.noalign = item.noalign;
-        e.cnt = item.cnt;
-        e.team = item.team;
-        e.spawnfunc_checked = true;
-               spawnfunc_item_minst_cells(e);
+               replace_with_insta_cells(item);
                return true;
        }
 
index cbc49be16513fa5d1cebbb2d3ed1724368f05910..67512a0a82a4c221a0b5bba2ea2e9750c5011c95 100644 (file)
@@ -4,15 +4,19 @@
 #include "rpc.qh"
 
 bool autocvar_g_overkill_powerups_replace;
-float autocvar_g_overkill_superguns_respawn_time;
-bool autocvar_g_overkill_100h_anyway;
-bool autocvar_g_overkill_100a_anyway;
+bool autocvar_g_overkill_ammo_charge;
+float autocvar_g_overkill_ammo_charge_notice;
+float autocvar_g_overkill_ammo_charge_limit;
+
+bool autocvar_g_overkill_filter_healthmega;
+bool autocvar_g_overkill_filter_armormedium;
+bool autocvar_g_overkill_filter_armorbig;
+bool autocvar_g_overkill_filter_armorlarge;
 
-.vector ok_deathloc;
-.float ok_spawnsys_timer;
-.Weapon ok_lastwep[MAX_WEAPONSLOTS];
 .float ok_item;
 
+.Weapon ok_lastwep[MAX_WEAPONSLOTS];
+
 void ok_Initialize();
 
 REGISTER_MUTATOR(ok, cvar("g_overkill") && !cvar("g_instagib") && !g_nexball && cvar_string("g_mod_balance") == "Overkill")
@@ -206,7 +210,7 @@ MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
                        wep.noalign = ent.noalign;
                        wep.cnt = ent.cnt;
                        wep.team = ent.team;
-                       wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
+                       wep.respawntime = g_pickup_respawntime_superweapon;
                        wep.pickup_anyway = true;
                        wep.spawnfunc_checked = true;
                        setthink(wep, self_spawnfunc_weapon_hmg);
@@ -223,7 +227,7 @@ MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
                        wep.noalign = ent.noalign;
                        wep.cnt = ent.cnt;
                        wep.team = ent.team;
-                       wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
+                       wep.respawntime = g_pickup_respawntime_superweapon;
                        wep.pickup_anyway = true;
                        wep.spawnfunc_checked = true;
                        setthink(wep, self_spawnfunc_weapon_rpc);
@@ -238,12 +242,16 @@ MUTATOR_HOOKFUNCTION(ok, FilterItem)
        entity item = M_ARGV(0, entity);
 
        if(item.ok_item)
-               return;
+               return false;
 
-       switch(item.items)
+       switch(item.itemdef)
        {
-               case ITEM_HealthMega.m_itemid: return !(autocvar_g_overkill_100h_anyway);
-               case ITEM_ArmorMega.m_itemid: return !(autocvar_g_overkill_100a_anyway);
+               case ITEM_HealthMega: return autocvar_g_overkill_filter_healthmega;
+               case ITEM_ArmorMedium: return autocvar_g_overkill_filter_armormedium;
+               // WARNING: next two statements look wrong because of inconsistency between cvar names and code
+               // armor cvars need renaming to be consistent with their health counterparts
+               case ITEM_ArmorLarge: return autocvar_g_overkill_filter_armorbig;
+               case ITEM_ArmorMega: return autocvar_g_overkill_filter_armorlarge;
        }
 
        return true;
index db5d29cefda9ec18af34da81e6e57708630c53a4..46e80fbc3e47aba9df7b2c659fa0ffa1b12eb6a5 100644 (file)
@@ -3,6 +3,9 @@
 #define IS_ONGROUND(s)                      boolean((s).flags & FL_ONGROUND)
 #define SET_ONGROUND(s)                     ((s).flags |= FL_ONGROUND)
 #define UNSET_ONGROUND(s)                   ((s).flags &= ~FL_ONGROUND)
+#define IS_ONSLICK(s)                                          boolean((s).flags & FL_ONSLICK)
+#define SET_ONSLICK(s)                                         ((s).flags |= FL_ONSLICK)
+#define UNSET_ONSLICK(s)                                       ((s).flags &= ~FL_ONSLICK)
 
 #ifdef CSQC
 .float bouncestop;
@@ -79,6 +82,8 @@ const int MOVETYPE_ANGLENOCLIP      = 1;
 const int MOVETYPE_ANGLECLIP        = 2;
 #endif
 
+const int FL_ONSLICK = BIT(20);
+
 const int MOVETYPE_FAKEPUSH         = 13;
 
 const int MOVEFLAG_VALID = BIT(23);
index f407be711134657178e65f1c957c808dd5358542..fd57e974ac8c242773500ec2edfd835655528adc 100644 (file)
@@ -314,7 +314,7 @@ bool PlayerJump(entity this)
        }
 
        if (!doublejump)
-               if (!IS_ONGROUND(this))
+               if (!IS_ONGROUND(this) && !IS_ONSLICK(this))
                        return IS_JUMP_HELD(this);
 
        bool track_jump = PHYS_CL_TRACK_CANJUMP(this);
@@ -351,7 +351,7 @@ bool PlayerJump(entity this)
                }
        }
 
-       if (!WAS_ONGROUND(this))
+       if (!WAS_ONGROUND(this) && !WAS_ONSLICK(this))
        {
 #ifdef SVQC
                if(autocvar_speedmeter)
@@ -373,6 +373,7 @@ bool PlayerJump(entity this)
        this.velocity_z += mjumpheight;
 
        UNSET_ONGROUND(this);
+       UNSET_ONSLICK(this);
        SET_JUMP_HELD(this);
 
 #ifdef SVQC
@@ -653,6 +654,24 @@ void PM_Footsteps(entity this)
 #endif
 }
 
+void PM_check_slick(entity this)
+{
+       if(!IS_ONGROUND(this))
+               return;
+
+       if(!PHYS_SLICK_APPLYGRAVITY(this))
+               return;
+
+       tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
+       if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
+       {
+               UNSET_ONGROUND(this);
+               SET_ONSLICK(this);
+       }
+       else
+               UNSET_ONSLICK(this);
+}
+
 void PM_check_blocked(entity this)
 {
 #ifdef SVQC
index 9f540148deb9b8c08908376e644c4c5e93a862a0..5c0b104178b0a385ee2509f9aa814f0d2b1c705c 100644 (file)
@@ -97,6 +97,8 @@ bool IsFlying(entity a);
 
 #define UPWARD_VELOCITY_CLEARS_ONGROUND(s)  STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, s)
 
+#define PHYS_SLICK_APPLYGRAVITY(s)             STAT(SLICK_APPLYGRAVITY, s)
+
 #define PHYS_INPUT_BUTTON_ATCK(s)           PHYS_INPUT_BUTTON_BUTTON1(s)
 #define PHYS_INPUT_BUTTON_JUMP(s)           PHYS_INPUT_BUTTON_BUTTON2(s)
 #define PHYS_INPUT_BUTTON_ATCK2(s)          PHYS_INPUT_BUTTON_BUTTON3(s)
@@ -156,6 +158,7 @@ STATIC_INIT(PHYS_INPUT_BUTTON_JETPACK)
 #define UNSET_JUMP_HELD(s)                  ((s).flags |= FL_JUMPRELEASED)
 
 #define WAS_ONGROUND(s)                     boolean((s).lastflags & FL_ONGROUND)
+#define WAS_ONSLICK(s)                      boolean((s).lastflags & FL_ONSLICK)
 
 #define ITEMS_STAT(s)                       ((s).items)
 
@@ -247,6 +250,8 @@ STATIC_INIT(PHYS_INPUT_BUTTON_JETPACK)
 
        bool Physics_Valid(string thecvar);
 
+       void Physics_UpdateStats(entity this, float maxspd_mod);
+
        .float stat_sv_airspeedlimit_nonqw = _STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW);
        .float stat_sv_maxspeed = _STAT(MOVEVARS_MAXSPEED);
 
index 0714f3b97fcb409905798272ff44d7ee39803c11..f9565db48bf0f54c4e57f893812b09a332c3dbcc 100644 (file)
@@ -255,6 +255,11 @@ REGISTER_STAT(CAMERA_SPECTATOR, int)
 
 REGISTER_STAT(SPECTATORSPEED, float)
 
+#ifdef SVQC
+bool autocvar_sv_slick_applygravity;
+#endif
+REGISTER_STAT(SLICK_APPLYGRAVITY, bool, autocvar_sv_slick_applygravity)
+
 #ifdef SVQC
 #include "physics/movetypes/movetypes.qh"
 #endif
index 13094e790aa527db25853d5a7f72944490c2b57b..d2c8ee06770202e2c23dc25b3fe3223caae385a9 100644 (file)
@@ -146,6 +146,7 @@ void func_breakable_behave_destroyed(entity this)
                stopsound (this, CH_TRIGGER_SINGLE);
 }
 
+void func_breakable_destroy(entity this, entity actor, entity trigger);
 void func_breakable_behave_restore(entity this)
 {
        this.health = this.max_health;
@@ -162,6 +163,8 @@ void func_breakable_behave_restore(entity this)
                this.bot_attack = true;
                this.event_damage = func_breakable_damage;
        }
+       if(this.spawnflags & 4)
+               this.use = func_breakable_destroy; // don't need to set it usually, as .use isn't reset
        this.state = 0;
        this.nextthink = 0; // cancel auto respawn
        func_breakable_colormod(this);
index c0a47e39b2a4aff558c3c53af50d49694d6c01f7..a08422dcfad666dd56780211cad37a9497dc17e3 100644 (file)
@@ -62,6 +62,8 @@ void sys_phys_update(entity this, float dt)
                goto end;
        }
 
+       PM_check_slick(this);
+
        if (IS_SVQC && !PHYS_FIXANGLE(this)) { this.angles = '0 1 0' * this.v_angle.y; }
        if (IS_PLAYER(this)) {
                if (IS_ONGROUND(this)) {
index ec35ccb616baa4835bcde47ef5b576fb790f7896..328917336368c11e38341337543f0d227bf1e2c3 100644 (file)
@@ -618,6 +618,8 @@ void PutClientInServer(entity this)
                FixPlayermodel(this);
                this.drawonlytoclient = NULL;
 
+               this.viewloc = NULL;
+
                this.crouch = false;
                this.view_ofs = STAT(PL_VIEW_OFS, this);
                setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
@@ -1213,6 +1215,9 @@ void ClientConnect(entity this)
        if (IS_REAL_CLIENT(this))
                sv_notice_join(this);
 
+       // update physics stats (players can spawn before physics runs)
+       Physics_UpdateStats(this, PHYS_HIGHSPEED(this));
+
        IL_EACH(g_initforplayer, it.init_for_player, {
                it.init_for_player(it, this);
        });
@@ -1674,6 +1679,7 @@ void SpectateCopy(entity this, entity spectatee)
        this.angles = spectatee.v_angle;
        STAT(FROZEN, this) = STAT(FROZEN, spectatee);
        this.revive_progress = spectatee.revive_progress;
+       this.viewloc = spectatee.viewloc;
        if(!PHYS_INPUT_BUTTON_USE(this) && STAT(CAMERA_SPECTATOR, this) != 2)
                this.fixangle = true;
        setorigin(this, spectatee.origin);
index 803e4376b3e29b0afee09d8fc88013343764d875..8e8dce9b12080abd58a7ff9ac91fd9bd2de9f317 100644 (file)
@@ -917,7 +917,8 @@ spawnfunc(worldspawn)
        if(cvar_string("g_mod_config") != cvar_defstring("g_mod_config"))
                modname = cvar_string("g_mod_config");
        // extra mutators that deserve to count as mod
-       MUTATOR_CALLHOOK(SetModname);
+       MUTATOR_CALLHOOK(SetModname, modname);
+       modname = M_ARGV(0, string);
 
        // save it for later
        modname = strzone(modname);
index 670e4c52ee2a70543675b9e6280d1ffa3dea24a7..2d19df72bfc5aa92011786a0177be6f4bff52678 100644 (file)
@@ -483,6 +483,7 @@ MUTATOR_HOOKABLE(SV_StartFrame, EV_NO_ARGS);
 
 #define EV_SetModname(i, o) \
     /** name of the mutator/mod if it warrants showing as such in the server browser */ \
+    /**/ i(string, MUTATOR_ARGV_0_string) \
     /**/ o(string, MUTATOR_ARGV_0_string) \
     /**/
 MUTATOR_HOOKABLE(SetModname, EV_SetModname);