.float runes;
+// Keys player is holding
+.float itemkeys;
+#define KEYS_GOLD_KEY 1
+#define KEYS_SILVER_KEY 2
+// spawnflags require key (for now only func_door)
+#define SPAWNFLAGS_GOLD_KEY 8
+#define SPAWNFLAGS_SILVER_KEY 16
+
.float version;
--- /dev/null
+/*
+Touch handler.
+*/
+void item_key_touch(void) {
+ if (other.classname != "player")
+ return;
+
+ // player already picked up this key
+ if (other.itemkeys & self.itemkeys)
+ return;
+
+ other.itemkeys |= self.itemkeys;
+
+ if (self.message)
+ centerprint(other, self.message);
+}
+
+/*
+Spawn a key with given model, key code and color.
+*/
+void spawn_item_key(float key_code) {
+ self.itemkeys = key_code;
+ precache_model(self.model);
+
+ if(self.spawnflags & 1)
+ self.noalign = 1;
+ if (self.noalign)
+ self.movetype = MOVETYPE_NONE;
+ else
+ self.movetype = MOVETYPE_TOSS;
+
+ setsize(self, '-16 -16 -24', '16 16 32');
+ setmodel(self, self.model);
+ self.modelflags |= MF_ROTATE;
+
+ if (!self.noalign)
+ {
+ // first nudge it off the floor a little bit to avoid math errors
+ setorigin(self, self.origin + '0 0 1');
+ // note droptofloor returns FALSE if stuck/or would fall too far
+ droptofloor();
+ }
+
+ self.touch = item_key_touch;
+}
+
+
+/*
+Spawn silver key.
+*/
+void spawnfunc_item_key1(void) {
+ if (!self.model)
+ self.model = "models/keys/key.md3";
+
+ if (!self.colormod)
+ self.colormod = '.9 .9 .9';
+
+ if (!self.message)
+ self.message = "You've picked up the silver key!";
+
+ spawn_item_key(KEYS_SILVER_KEY);
+}
+
+/*
+Spawn gold key.
+*/
+void spawnfunc_item_key2(void) {
+ if (!self.model)
+ self.model = "models/keys/key.md3";
+
+ if (!self.colormod)
+ self.colormod = '1 .9 0';
+
+ if (!self.message)
+ self.message = "You've picked up the gold key!";
+
+ spawn_item_key(KEYS_GOLD_KEY);
+}
+
+
t_items.qc
cl_weapons.qc
cl_impulse.qc
+item_key.qc
ent_cs.qc
void door_trigger_touch()
{
if (other.health < 1)
- if not(other.iscreature && other.deadflag == DEAD_NO)
- return;
+ if not(other.iscreature && other.deadflag == DEAD_NO)
+ return;
if (time < self.attack_finished_single)
return;
+
+ if (self.spawnflags & (SPAWNFLAGS_GOLD_KEY | SPAWNFLAGS_SILVER_KEY)) {
+ // this door require a key
+ // only a player can have a key
+ if (other.classname != "player")
+ return;
+
+ // check gold key
+ if (self.spawnflags & SPAWNFLAGS_GOLD_KEY)
+ if (!(other.itemkeys & KEYS_GOLD_KEY)) {
+ centerprint(other, "You don't have the gold key");
+ return;
+ }
+
+ // check silver key
+ if (self.spawnflags & SPAWNFLAGS_SILVER_KEY)
+ if (!(other.itemkeys & KEYS_SILVER_KEY)) {
+ centerprint(other, "You don't have the silver key");
+ return;
+ }
+ }
+
self.attack_finished_single = time + 1;
activator = other;
if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
return;
self.health = self.health - damage;
+
+ if (self.spawnflags & SPAWNFLAGS_GOLD_KEY || self.spawnflags & SPAWNFLAGS_SILVER_KEY) {
+ // don't allow opening doors through damage if keys are required
+ return;
+ }
+
if (self.health <= 0)
{
oself = self;
};
-/*QUAKED spawnfunc_func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK x x TOGGLE
+/*QUAKED spawnfunc_func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE
if two doors touch, they are assumed to be connected and operate as a unit.
TOGGLE causes the door to wait in both the start and end states for a trigger event.
START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
+GOLD_KEY causes the door to open only if the activator holds a gold key.
+
+SILVER_KEY causes the door to open only if the activator holds a silver key.
+
"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
"angle" determines the opening direction
"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.