]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Support door keys on QL maps
authorbones_was_here <bones_was_here@xonotic.au>
Sat, 16 Mar 2024 06:36:03 +0000 (16:36 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Wed, 17 Apr 2024 14:49:36 +0000 (00:49 +1000)
Also adds a MASTER key for Xonotic mapping (useful for secrets...)

Removes blind nudging of keys as was done for normal items in cc83c39c27ea0757cf169562428e443c5ab60fdc

qcsrc/common/mapobjects/func/door.qc
qcsrc/common/mapobjects/func/door.qh
qcsrc/common/mapobjects/misc/keys.qc
qcsrc/server/compat/quake3.qc

index f24bdb45b53cc69635f204bbcc2f4e38d4158225..0250b48cf0b7ee87908791f47279a25b15b8269d 100644 (file)
@@ -750,7 +750,7 @@ void door_init_shared(entity this)
 // spawnflags require key (for now only func_door)
 spawnfunc(func_door)
 {
-       // Quake 1 keys compatibility
+       // Quake 1 and QL keys compatibility
        if (this.spawnflags & SPAWNFLAGS_GOLD_KEY)
                this.itemkeys |= ITEM_KEY_BIT(0);
        if (this.spawnflags & SPAWNFLAGS_SILVER_KEY)
index ce7025dd5488854e741bb166c9c3e2db8b1a8f2a..44888da6a1fd95ee356dc0cdc898eb4bfab10d43 100644 (file)
@@ -6,8 +6,8 @@ bool autocvar_sv_doors_always_open;
 
 const int DOOR_START_OPEN = BIT(0); // has same meaning in Q3: reverse position 1 and 2
 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 SPAWNFLAGS_GOLD_KEY = BIT(3); // Quake 1 and QL compat, can only be used with func_door!
+const int SPAWNFLAGS_SILVER_KEY = BIT(4); // Quake 1 and QL compat, can only be used with func_door!
 const int DOOR_TOGGLE = BIT(5);
 
 const int DOOR_NONSOLID = BIT(10);
index 89f6fa8f94def1d4f61550cc47a6511d008a2a53..1b2b88e056aa14fa69b84075909adc456e13687b 100644 (file)
@@ -112,19 +112,21 @@ void spawn_item_key(entity this)
        this.mdl = this.model;
        this.effects = EF_LOWPRECISION;
        _setmodel(this, this.model);
+       this.modelflags |= MF_ROTATE;
+       this.solid = SOLID_TRIGGER;
+
+       // The origin.z was raised within the bbox to support the current model
        //setsize(this, '-16 -16 -24', '16 16 32');
        setorigin(this, this.origin + '0 0 32');
        setsize(this, '-16 -16 -56', '16 16 0');
-       this.modelflags |= MF_ROTATE;
-       this.solid = SOLID_TRIGGER;
 
+       if (Q3COMPAT_COMMON) // QL compat, Q3 has no keys
+               // QL bbox is '-16 -16 -16' '16 16 16' so raise to match QL absmin.z
+               setorigin(this, this.origin + '0 0 8');
+
+       // NOTE: this isn't an FL_ITEM so it doesn't get the special treatment in DropToFloor_QC()
        if (!this.noalign)
-       {
-               // first nudge it off the floor a little bit to avoid math errors
-               setorigin(this, this.origin + '0 0 1');
-               // note droptofloor returns false if stuck/or would fall too far
                droptofloor(this);
-       }
 
        settouch(this, item_key_touch);
 }
@@ -132,16 +134,19 @@ void spawn_item_key(entity this)
 
 /*QUAKED item_key (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
 A key entity.
-The itemkeys should contain one of the following key IDs:
+The itemkeys bitfield should contain one of the following key IDs:
 1 - GOLD key -
 2 - SILVER key
 4 - BRONZE key
 8 - RED keycard
 16 - BLUE keycard
 32 - GREEN keycard
+16777215 (0xffffff) - MASTER key (all 24 bits set)
 Custom keys:
-... - last key is 1<<23
-Keys with bigger Id than 32 don't have a default netname and model, if you use one of them, you MUST provide those.
+    - first key ID is 64
+    - last key ID is 8388608 (1<<23 or 0x800000)
+Keys (other than master keys) with bigger ID than 32 don't have a default netname and model,
+if you use one of them, you MUST provide those.
 -----------KEYS------------
 colormod: color of the key (default: '.9 .9 .9').
 itemkeys: a key Id.
@@ -154,7 +159,7 @@ FLOATING: the item will float in air, instead of aligning to the floor by fallin
 ---------NOTES----------
 This is the only correct way to put keys on the map!
 
-itemkeys MUST always have exactly one bit set.
+itemkeys MUST always have exactly one bit set (unless it's a master key).
 */
 spawnfunc(item_key)
 {
@@ -162,7 +167,9 @@ spawnfunc(item_key)
        vector _colormod;
 
        // reject this entity if more than one key was set!
-       if (this.itemkeys>0 && (this.itemkeys & (this.itemkeys-1)) != 0) {
+       if (this.itemkeys>0 && (this.itemkeys & (this.itemkeys-1)) != 0)
+       if (this.itemkeys != 0xffffff) // unless it's a master key
+       {
                objerror(this, "item_key.itemkeys must contain only 1 bit set specifying the key it represents!");
                delete(this);
                return;
@@ -200,6 +207,11 @@ spawnfunc(item_key)
                _colormod = '0 .9 0';
                break;
 
+       case 0xffffff: // an unlisted key...
+               _netname = "MASTER key";
+               _colormod = '1 0.25 0.25';
+               break;
+
        default:
                _netname = "FLUFFY PINK keycard";
                _colormod = '1 1 1';
@@ -215,7 +227,7 @@ spawnfunc(item_key)
 
        // find default model
        string _model = string_null;
-       if (this.itemkeys <= ITEM_KEY_BIT(2)) {
+       if (this.itemkeys <= ITEM_KEY_BIT(2) || this.itemkeys == 0xffffff) {
                _model = "models/keys/key.md3";
        } else if (this.itemkeys >= ITEM_KEY_BIT(3) && this.itemkeys <= ITEM_KEY_BIT(5)) {
                _model = "models/keys/key.md3"; // FIXME: replace it by a keycard model!
@@ -287,4 +299,40 @@ spawnfunc(item_key2)
        spawnfunc_item_key(this);
 }
 
+       // Quake Live Keys
+/*QUAKED item_key_gold (1 .66 0) (-16 -16 -16) (16 16 16) SUSPENDED */
+spawnfunc(item_key_gold)
+{
+       this.itemkeys = BIT(0);
+       spawnfunc_item_key(this);
+}
+/*QUAKED item_key_silver (.56 .56 .56) (-16 -16 -16) (16 16 16) SUSPENDED */
+spawnfunc(item_key_silver)
+{
+       this.itemkeys = BIT(1);
+       spawnfunc_item_key(this);
+}
+/*QUAKED item_key_master (1 0 0) (-16 -16 -16) (16 16 16) SUSPENDED
+Master key, opens silver and gold doors.
+
+-------- KEYS --------
+target : picking up the item will trigger the entity this points to.
+targetname : a target_give entity can point to this for respawn freebies.
+notfree : when set to 1, entity will not spawn in "Free for all", "Race", and "Duel" modes.
+notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
+notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
+not_gametype : space delineated list of gametype shortnames (ffa duel race tdm ca ctf 1f ob har ft dom ad rr) in which to inhibit the entity.
+gametype : space delineated list of gametype shortnames (ffa duel race tdm ca ctf 1f ob har ft dom ad rr) to only spawn entity in this gametype.
+notbot : when set to 1, used to make an item invisible for bot attraction.
+
+-------- SPAWNFLAGS --------
+1 = suspended : item will spawn where it was placed in map and won't drop to the floor.
+*/
+spawnfunc(item_key_master)
+{
+       // We have more key types than QL, may as well open them all.
+       this.itemkeys = 0xffffff;
+       spawnfunc_item_key(this);
+}
+
 #endif
index 68a475e790a88a27bf4e50ccd3dd3ab5ad954e20..e3c949a98ead5c11b62de807d016781e13bbe55d 100644 (file)
@@ -37,6 +37,9 @@
  item_health_small           Q3A    health.qh
  item_health_mega            Q3A    health.qh
  item_regen                  Q3A    buffs/all.inc
+ item_key_gold               QL     keys.qc
+ item_key_silver             QL     keys.qc
+ item_key_master             QL     keys.qc
  weapon_machinegun           Q3A    machinegun.qh
  weapon_grenadelauncher      Q3A    mortar.qh
  weapon_rocketlauncher       Q3A    devastator.qh