]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'Mario/minor_fixes' into 'master'
authorterencehill <piuntn@gmail.com>
Sun, 25 Dec 2022 02:08:11 +0000 (02:08 +0000)
committerterencehill <piuntn@gmail.com>
Sun, 25 Dec 2022 02:08:11 +0000 (02:08 +0000)
Several fixes for minor issues

Closes #2135, #2360, #2704, #2734, #2749, and #2751

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

gamemodes-server.cfg
monsters.cfg
qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc
qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qh
qcsrc/common/gamemodes/gamemode/cts/sv_cts.qc
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/server/command/vote.qc
qcsrc/server/items/items.qc
qcsrc/server/weapons/common.qc

index a822fc9a64e51d41392ebc849860a732a503b0ec..a7379ed40f85ff6d7841e747e85aeb6914218838 100644 (file)
@@ -260,7 +260,7 @@ set g_ctf_stalemate 1 "show the enemy flagcarrier location after both teams have
 set g_ctf_stalemate_endcondition 1 "condition for stalemate mode to be finished: 1 = If ONE flag is no longer stale, 2 = If BOTH flags are no longer stale"
 set g_ctf_stalemate_time 60 "time for each flag until stalemate mode is activated"
 set g_ctf_flagcarrier_waypointforenemy_spotting 1 "show the enemy flagcarrier location if a team mate presses +use to spot them"
-set g_ctf_dropped_capture_delay 1.5 "autocapture delay when flag is thrown onto the base - counted from throw, not landing"
+set g_ctf_dropped_capture_delay 1 "autocapture delay when flag is thrown onto the base - counted from when the flag lands on the ground"
 set g_ctf_dropped_capture_radius 100 "allow dropped flags to be automatically captured by base flags if the dropped flag is within this radius of it"
 set g_ctf_flag_damageforcescale 2
 set g_ctf_portalteleport 0 "allow flag carriers to go through portals made in portal gun without dropping the flag"
@@ -326,6 +326,7 @@ set g_cts_selfdamage 1 "0 = disable all selfdamage and falldamage in cts"
 set g_cts_finish_kill_delay 2 "kill player this many seconds after stage completion to prevent cheating by starting out with more speed than otherwise possible; set it to 0 to not kill or to -1 to kill instantly"
 set g_cts_send_rankings_cnt 15 "send this number of map records to clients"
 set g_cts_removeprojectiles 0 "remove projectiles when the player dies, to prevent using weapons earlier in the stage than intended"
+set g_cts_drop_monster_items 0 "allow killed monsters to drop their items"
 
 
 // ==========================
index 3f94f96319e05a1452863c5380e46d6ebfc2eaf6..94e25eb47d422eb1eb1eba6cd42ff751966746f8 100644 (file)
@@ -52,7 +52,6 @@ set g_monster_mage_heal_allies 20
 set g_monster_mage_heal_delay 1.5
 set g_monster_mage_heal_minhealth 250
 set g_monster_mage_heal_range 250
-set g_monster_mage_heal_self 40
 set g_monster_mage_health 400
 set g_monster_mage_shield_blockpercent 0.8
 set g_monster_mage_shield_delay 7
index a1e1c59900ba4ac5ac435e8dcdc73d431f0bc57a..91952b2d15746ce085923c62007e35213717722d 100644 (file)
@@ -356,6 +356,7 @@ void ctf_Handle_Drop(entity flag, entity player, int droptype)
        flag.angles = '0 0 0';
        SetResourceExplicit(flag, RES_HEALTH, flag.max_health);
        flag.ctf_droptime = time;
+       flag.ctf_landtime = 0;
        flag.ctf_dropper = player;
        flag.ctf_status = FLAG_DROPPED;
 
@@ -473,6 +474,7 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype)
        flag.solid = SOLID_TRIGGER;
        flag.ctf_dropper = player;
        flag.ctf_droptime = time;
+       flag.ctf_landtime = 0;
 
        flag.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND for MOVETYPE_TOSS
 
@@ -949,7 +951,7 @@ void ctf_FlagThink(entity this)
                                for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
                                        if(tmp_entity.ctf_status == FLAG_DROPPED)
                                        if(vdist(this.origin - tmp_entity.origin, <, autocvar_g_ctf_dropped_capture_radius))
-                                       if(time > tmp_entity.ctf_droptime + autocvar_g_ctf_dropped_capture_delay)
+                                       if((this.noalign || tmp_entity.ctf_landtime) && time > ((this.noalign) ? tmp_entity.ctf_droptime : tmp_entity.ctf_landtime) + autocvar_g_ctf_dropped_capture_delay)
                                                ctf_Handle_Capture(this, tmp_entity, CAPTURE_DROPPED);
                        }
                        return;
@@ -958,6 +960,8 @@ void ctf_FlagThink(entity this)
                case FLAG_DROPPED:
                {
                        this.angles = '0 0 0'; // reset flag angles in case warpzones adjust it
+                       if(IS_ONGROUND(this) && !this.ctf_landtime)
+                               this.ctf_landtime = time; // landtime is reset when thrown, and we don't want to restart the timer if the flag is pushed
 
                        if(autocvar_g_ctf_flag_dropped_floatinwater)
                        {
@@ -1210,6 +1214,7 @@ void ctf_RespawnFlag(entity flag)
        flag.ctf_dropper = NULL;
        flag.ctf_pickuptime = 0;
        flag.ctf_droptime = 0;
+       flag.ctf_landtime = 0;
        flag.ctf_flagdamaged_byworld = false;
        navigation_dynamicgoal_unset(flag);
 
index 519cbd0648f49eaaaffceb7863fc4f2abea24ed2..adb061809fe053f56c36f763e31fb7195e0e3928 100644 (file)
@@ -135,6 +135,7 @@ bool ctf_stalemate; // indicates that a stalemate is active
 float ctf_captimerecord; // record time for capturing the flag
 .float ctf_pickuptime;
 .float ctf_droptime;
+.float ctf_landtime;
 .int ctf_status; // status of the flag (FLAG_BASE, FLAG_DROPPED, FLAG_CARRY declared globally)
 .entity ctf_dropper; // don't allow spam of dropping the flag
 .float next_take_time;
index 56de4a90cf86d9912b532331bfb7ce622996b2e8..0fbab7ae51f54159e1913b7fe723bd4795b77ed4 100644 (file)
@@ -12,6 +12,7 @@
 float autocvar_g_cts_finish_kill_delay;
 bool autocvar_g_cts_selfdamage;
 bool autocvar_g_cts_removeprojectiles;
+bool autocvar_g_cts_drop_monster_items;
 
 // legacy bot roles
 .float race_checkpoint;
@@ -284,6 +285,8 @@ MUTATOR_HOOKFUNCTION(cts, FilterItem)
 
        if (Item_IsLoot(item))
        {
+               if(item.monster_loot && autocvar_g_cts_drop_monster_items)
+                       return false;
                return true;
        }
 }
index 8cfa77e6535aa7dfe70925d12a58cb02b9bb4537..f3da794ba517834f3f42e1e66b0ffdabeacd5743 100644 (file)
@@ -24,7 +24,6 @@ float autocvar_g_monster_mage_attack_teleport_chance = 0.2;
 float autocvar_g_monster_mage_attack_teleport_delay = 2;
 float autocvar_g_monster_mage_attack_teleport_random = 0.4;
 float autocvar_g_monster_mage_attack_teleport_random_range = 1200;
-float autocvar_g_monster_mage_heal_self;
 float autocvar_g_monster_mage_heal_allies;
 float autocvar_g_monster_mage_heal_minhealth;
 float autocvar_g_monster_mage_heal_range;
@@ -108,7 +107,6 @@ bool M_Mage_Defend_Heal_Check(entity this, entity targ)
                                        );
                }
                case 2: return (GetResource(targ, RES_ARMOR) < autocvar_g_balance_armor_regenstable);
-               case 3: return (GetResource(targ, RES_HEALTH) > 0);
        }
 
        return false;
@@ -254,11 +252,6 @@ void M_Mage_Defend_Heal(entity this)
                                                fx = EFFECT_ARMOR_REPAIR;
                                        }
                                        break;
-                               case 3:
-                                       float hp = ((it == this) ? autocvar_g_monster_mage_heal_self : autocvar_g_monster_mage_heal_allies);
-                                       TakeResource(it, RES_HEALTH, hp); // TODO: use regular damage functions? needs a way to bypass friendly fire checks
-                                       fx = EFFECT_RAGE;
-                                       break;
                        }
 
                        Send_Effect(fx, it.origin, '0 0 0', 1);
index e88b35f4554aec593a5a922d09ebf0656e0de33a..1635b5cb0d235c6eeb84dac673c18d98e9421e96 100644 (file)
@@ -55,6 +55,8 @@ void monster_dropitem(entity this, entity attacker)
        {
                e.noalign = true;
                StartItem(e, e.monster_loot);
+               if(startitem_failed || wasfreed(e))
+                       return;
                e.gravity = 1;
                setorigin(e, org);
                e.velocity = randomvec() * 175 + '0 0 325';
@@ -884,6 +886,12 @@ bool Monster_Appear_Check(entity this, Monster monster_id)
 
 void Monster_Reset(entity this)
 {
+       if(this.spawnflags & MONSTERFLAG_SPAWNED)
+       {
+               Monster_Remove(this);
+               return;
+       }
+
        setorigin(this, this.pos1);
        this.angles = this.pos2;
 
index de5524526c9585b00d347a246431c6e41c2d7d0a..b360f34d3f325133ee88629f26110d54a5f508d8 100644 (file)
@@ -559,9 +559,9 @@ void ReadyCount()
 //  Supporting functions for VoteCommand
 // ======================================
 
-float Votecommand_check_assignment(entity caller, float assignment)
+bool Votecommand_check_assignment(entity caller, float assignment)
 {
-       float from_server = (!caller);
+       bool from_server = (!caller);
 
        if ((assignment == VC_ASGNMNT_BOTH)
            || ((!from_server && assignment == VC_ASGNMNT_CLIENTONLY)
@@ -580,33 +580,32 @@ string VoteCommand_extractcommand(string input, float startpos, int argc)
        return output;
 }
 
-float VoteCommand_checknasty(string vote_command)
+bool VoteCommand_checknasty(string vote_command)
 {
-       if ((strstrofs(vote_command, ";", 0) >= 0)
+       return !((strstrofs(vote_command, ";", 0) >= 0)
            || (strstrofs(vote_command, "\n", 0) >= 0)
            || (strstrofs(vote_command, "\r", 0) >= 0)
-           || (strstrofs(vote_command, "$", 0) >= 0)) return false;
-
-       return true;
+           || (strstrofs(vote_command, "$", 0) >= 0));
 }
 
 // NOTE: requires input to be surrounded by spaces
 string VoteCommand_checkreplacements(string input)
 {
-       string output = input;
+       // add a space around the input so the start and end of the list is captured
+       string output = strcat(" ", input, " ");
        // allow gotomap replacements
        output = strreplace(" map ", " gotomap ", output);
        output = strreplace(" chmap ", " gotomap ", output);
        return output;
 }
 
-float VoteCommand_checkinlist(string vote_command, string list)
+bool VoteCommand_checkinlist(string vote_command, string list)
 {
-       string l = VoteCommand_checkreplacements(strcat(" ", list, " "));
+       if (vote_command == "" || list == "")
+               return false;
 
-       if (strstrofs(l, VoteCommand_checkreplacements(strcat(" ", vote_command, " ")), 0) >= 0) return true;
-
-       return false;
+       string l = VoteCommand_checkreplacements(list);
+       return (strstrofs(l, VoteCommand_checkreplacements(vote_command), 0) >= 0);
 }
 
 string ValidateMap(string validated_map, entity caller)
index 7f3a1c7c1132f3641d51c4d7a670bbb187572d18..5e900a603977c0b12cc1eb6d834dd545aa699e6e 100644 (file)
@@ -1162,7 +1162,7 @@ void StartItem(entity this, GameItem def)
        if (def.spawnflags & ITEM_FLAG_MUTATORBLOCKED)
        {
                delete(this);
-               return;
+               return; // TODO does not set startitem_failed
        }
 
        this.classname = def.m_canonical_spawnfunc;
index a00eb120ee8d9fa213e8e8fea68f4241220642bb..ff6f8ea4cb18659650fb36e751c76fef2d7909cd 100644 (file)
@@ -120,11 +120,14 @@ bool SUB_NoImpactCheck(entity this, entity toucher)
        // mirror-impact of something hitting the projectile instead of the
        // projectile hitting the something, or a touchareagrid one. Neither of
        // these stop the projectile from moving, so...
+       // NOTE: this notice is disabled to prevent spam as projectiles can hit content-less objects (other projectiles!)
+#if 0
        if(trace_dphitcontents == 0)
        {
                LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct. (edict: %i, classname: %s, origin: %v)", this, this.classname, this.origin);
                checkclient(this); // TODO: .health is checked in the engine with this, possibly replace with a QC function?
        }
+#endif
     if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
         return true;
     if (toucher == NULL && this.size != '0 0 0')
@@ -135,7 +138,8 @@ bool SUB_NoImpactCheck(entity this, entity toucher)
         traceline(this.origin - tic, this.origin + tic, MOVE_NORMAL, this);
         if (trace_fraction >= 1)
         {
-            LOG_TRACE("Odd... did not hit...?");
+            // NOTE: this notice can occur when projectiles hit non-world objects, better to not spam the console!
+            //LOG_TRACE("Odd... did not hit...?");
         }
         else if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
         {