djcev.com

//

Git Repos / fte_dogmode / qc / items / keys.qc

Last update to this file was on 2024-03-24 at 02:40.

Show keys.qc

//==============================================================================
// KEYS
//==============================================================================

//======================================================================
// constants
//======================================================================

// The highest bitflag that will be assigned to a custom key.
const float FINAL_CUSTOM_KEY = 4194304;

//======================================================================
// globals
//======================================================================

// The highest bitflag that has been assigned to a custom key.
float highest_custom_key;

//======================================================================
// fields
//======================================================================

.float customkeys; // support for item_key_custom -- iw
.string keyname;

//======================================================================
// forward declarations
//======================================================================

// temp_keydef
entity(string key_name) spawn_temp_keydef;
void(entity e) temp_keydef_init;
strip void() temp_keydef;

// base_item_key
string() base_item_key_silvername;
string() base_item_key_goldname;
entity(string key_name) base_item_key_find_keydef;
float(string key_name) base_item_key_customflag;
float(entity client, float flags, float custom_flags) base_item_key_haskeys;
void(entity client, float flags, float custom_flags) base_item_key_givekeys;
void(entity client) base_item_key_giveallkeys;
void(entity client, float flags, float custom_flags) base_item_key_removekeys;
void() base_item_key_touch;
void(entity e) base_item_key_init;
strip void() base_item_key;

// item_key1
entity(entity src) item_key1_drop;
entity(entity src, vector org, vector vel) spawn_item_key1;
void(entity e) item_key1_init;
void() item_key1;

// item_key2
entity(entity src) item_key2_drop;
entity(entity src, vector org, vector vel) spawn_item_key2;
void(entity e) item_key2_init;
void() item_key2;

// item_key_custom
entity(entity src, vector org, vector vel, string kname) spawn_item_key_custom;
void(entity e) item_key_custom_init;
void() item_key_custom;

//------------------------------------------------------------------------------

//----------------------------------------------------------------------
// class temp_keydef: base_tempentity
// {
//--------------------------------------------------------------
// SpawnCustomKeyDef
//
// Spawn and return a new custom_key_def entity which will define
// the custom key named key_name.
//
// The value of the entity's customkeys field will be a bitflag
// which has not yet been used to represent a custom key. -- iw
//--------------------------------------------------------------
entity(string key_name) spawn_temp_keydef =
{
if (highest_custom_key == FINAL_CUSTOM_KEY)
error ("too many custom keys");

if (highest_custom_key == 0)
highest_custom_key = 1;
else
highest_custom_key = highest_custom_key * 2;

local entity e = spawn ();
e.netname = key_name;
e.customkeys = highest_custom_key;
temp_keydef_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) temp_keydef_init =
{
base_tempentity_init (e);
e.classname = "custom_key_def";
e.classtype = CT_TEMP_KEYDEF;
};

//--------------------------------------------------------------
strip void() temp_keydef =
{
temp_keydef_init (self);
};
// };

//----------------------------------------------------------------------
// class base_item_key: base_item
// {
//==============================================================
// FUNCTIONS WHICH DEAL WITH KEY ITEM BITFLAGS AND NAMES
//==============================================================

/*
================================================================
The functions below were created for progs_dump by Ian "iw" Walshaw,
January 2020.

They define functions which deal with the bitflags and names which
refer to the key items, including the new item_key_custom.

These functions are a dependency of the updated code for the key
items (in items.qc [now in items/keys.qc -- CEV]) and also the
updated code for unlockable entities (in keylock.qc).
================================================================
*/

//--------------------------------------------------------------
// SilverKeyName
//
// Return the name that should be used for the silver key as per
// world.worldtype. -- iw
//--------------------------------------------------------------
string() base_item_key_silvername =
{
if (world.worldtype == WORLDTYPE_BASE)
return "silver keycard";
if (world.worldtype == WORLDTYPE_METAL)
return "silver runekey";
return "silver key";
};

//--------------------------------------------------------------
// GoldKeyName
//
// Return the name that should be used for the gold key as per
// world.worldtype. -- iw
//--------------------------------------------------------------
string() base_item_key_goldname =
{
if (world.worldtype == WORLDTYPE_BASE)
return "gold keycard";
if (world.worldtype == WORLDTYPE_METAL)
return "gold runekey";
return "gold key";
};

//--------------------------------------------------------------
// FindCustomKeyDef
//
// If a custom_key_def entity exists which defines the custom key
// named key_name, then find and return it, otherwise return world.
//
// If a custom_key_def entity is returned, then the value of its
// customkeys field will be the bitflag that should be used to
// represent the custom key named key_name. -- iw
//--------------------------------------------------------------
entity(string key_name) base_item_key_find_keydef =
{
local entity keydef;

keydef = findfloat (world, classtype, CT_TEMP_KEYDEF);
while (keydef != world)
{
if (keydef.netname == key_name)
return keydef;
keydef = findfloat (keydef, classtype, CT_TEMP_KEYDEF);
}
return world;
};

//--------------------------------------------------------------
// CustomKeyFlag
//
// Return the bitflag that should be used to represent the custom
// key named key_name.
//
// More specifically, if this is the first time that this function
// has been called for the specified key_name, then return a bitflag
// which has not previously been returned by this function for
// anykey_name. Otherwise, return the same bitflag that was
// previously returned for the specified key_name. -- iw
//--------------------------------------------------------------
float(string key_name) base_item_key_customflag =
{
local entity keydef;

keydef = base_item_key_find_keydef (key_name);
if (keydef == world)
keydef = spawn_temp_keydef (key_name);
return keydef.customkeys;
};

//--------------------------------------------------------------
// HasKeys
//
// Return TRUE if the specified client has all of the non-custom
// keys represented by the flags and all of the custom keys
// represented by the custom_flags, otherwise return FALSE. -- iw
//--------------------------------------------------------------
float(entity client, float flags, float custom_flags)
base_item_key_haskeys =
{
return (client.items & flags) == flags &&
(client.customkeys & custom_flags) == custom_flags;
};

//--------------------------------------------------------------
// GiveKeys
//
// Give the specified client all of the non-custom keys represented
// by the item_flags and all of the custom keys represented by the
// customkey_flags. -- iw
//--------------------------------------------------------------
void(entity client, float flags, float custom_flags)
base_item_key_givekeys =
{
client.items = client.items | flags;
client.customkeys = client.customkeys | custom_flags;
};

//--------------------------------------------------------------
// GiveAllKeys
//
// Give the specified client the silver key, the gold key, and
// all of the custom keys that have been defined for the current
// map. -- iw
//--------------------------------------------------------------
void(entity client) base_item_key_giveallkeys =
{
base_item_key_givekeys (client, IT_KEY1 | IT_KEY2,
highest_custom_key * 2 - 1);
};

//--------------------------------------------------------------
// RemoveKeys
//
// Remove all of the non-custom keys represented by the item_flags
// and all of the custom keys represented by the customkey_flags
// from the specified client's inventory. -- iw
//--------------------------------------------------------------
void(entity client, float flags, float custom_flags)
base_item_key_removekeys =
{
client.items = client.items - (client.items & flags);
client.customkeys = client.customkeys -
(client.customkeys & custom_flags);
};

//==============================================================
// End iw's excellent key handling functions (what was previously
// keydata.qc) -- CEV
//==============================================================

//--------------------------------------------------------------
// was key_touch -- CEV
//--------------------------------------------------------------
void() base_item_key_touch =
{
if (sub_checkvalidtouch(other) == FALSE)
return;

// support for item_key_custom -- iw
if (base_item_key_haskeys(other, self.items, self.customkeys))
return;

sprint (other, sprintf("You got the %s\n", self.netname));

sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");

// support for item_key_custom -- iw
base_item_key_givekeys (other, self.items, self.customkeys);

if (!coop)
{
self.solid = SOLID_NOT;
self.model = __NULL__;
}

activator = other;
// fix key items firing their targets multiple times in coop
// -- iw
// fire all targets / killtargets
sub_useandforgettargets ();
};

//--------------------------------------------------------------
// key_start -- Finish initializing self as a key item. -- iw
//--------------------------------------------------------------
void(entity e) base_item_key_init =
{
e.classgroup |= CG_ITEM_KEY;

// key_setsounds
// support for item_key_custom -- iw
if (e.noise != "")
{
precache_sound (e.noise);
}
else
{
if (world.worldtype == WORLDTYPE_MEDIEVAL)
{
precache_sound ("misc/medkey.wav");
e.noise = "misc/medkey.wav";
}
else if (world.worldtype == WORLDTYPE_METAL)
{
precache_sound ("misc/runekey.wav");
e.noise = "misc/runekey.wav";
}
else if (world.worldtype == WORLDTYPE_BASE)
{
precache_sound2 ("misc/basekey.wav");
e.noise = "misc/basekey.wav";
}
}

// key_start
e.particles_offset = '0 0 18';
e.pos1 = '-16 -16 -24';
e.pos2 = '16 16 32';

// StartItem
base_item_init (e);
};

//--------------------------------------------------------------
strip void() base_item_key =
{
base_item_key_init (self);
};
// };

/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/w_s_key.mdl"); }
SILVER key
In order for keys to work you MUST set your map's worldtype to one of the following:
0: medieval
1: metal
2: base
*/
//----------------------------------------------------------------------
// class item_key1: base_item_key
// {
//--------------------------------------------------------------
entity(entity src) item_key1_drop =
{
local entity e;
local vector vel;
vel_x = -100 + (random() * 200);
vel_y = -100 + (random() * 200);
vel_z = 300;
e = spawn_item_key1 (src, src.origin - '0 0 24', vel);
e.effects = EF_DIMLIGHT;
return e;
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel) spawn_item_key1 =
{
local entity e = spawn ();
e.owner = src;
e.origin = org;
e.velocity = vel;
item_key1_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) item_key1_init =
{
e.classname = "item_key1";
e.classtype = CT_ITEM_KEY1;
e.touch = base_item_key_touch;

if (world.worldtype == WORLDTYPE_MEDIEVAL)
{
precache_body_model (e, "progs/w_s_key.mdl");
body_model (e, "progs/w_s_key.mdl");
}
else if (world.worldtype == WORLDTYPE_METAL)
{
precache_body_model (e, "progs/m_s_key.mdl");
body_model (e, "progs/m_s_key.mdl");
}
else if (world.worldtype == WORLDTYPE_BASE)
{
precache_body_model2 (e, "progs/b_s_key.mdl");
body_model (e, "progs/b_s_key.mdl");
}

if (e.keyname != "")
e.netname = e.keyname;
else
e.netname = base_item_key_silvername ();

e.items = IT_KEY1;

// support for item_key_custom -- iw
e.customkeys = 0; // ignore any mapper-set value
e.noise = ""; // ignore any mapper-set value

// key_start
base_item_key_init (e);
};

//--------------------------------------------------------------
void() item_key1 =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

item_key1_init (self);
};
// };

/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/w_g_key.mdl");
}
GOLD key
In order for keys to work you MUST set your map's worldtype to one of the following:
0: medieval
1: metal
2: base
*/
//----------------------------------------------------------------------
// class item_key2: base_item_key
// {
//--------------------------------------------------------------
entity(entity src) item_key2_drop =
{
local entity e;
local vector vel;
vel_x = -100 + (random() * 200);
vel_y = -100 + (random() * 200);
vel_z = 300;
e = spawn_item_key2 (src, src.origin - '0 0 24', vel);
e.effects = EF_DIMLIGHT;
return e;
};

//--------------------------------------------------------------
entity(entity src, vector org, vector vel) spawn_item_key2 =
{
local entity e = spawn ();
e.owner = src;
e.origin = org;
e.velocity = vel;
item_key2_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) item_key2_init =
{
e.classname = "item_key2";
e.classtype = CT_ITEM_KEY2;
e.touch = base_item_key_touch;

if (world.worldtype == WORLDTYPE_MEDIEVAL)
{
precache_body_model (e, "progs/w_g_key.mdl");
body_model (e, "progs/w_g_key.mdl");
}
else if (world.worldtype == WORLDTYPE_METAL)
{
precache_body_model (e, "progs/m_g_key.mdl");
body_model (e, "progs/m_g_key.mdl");
}
else if (world.worldtype == WORLDTYPE_BASE)
{
precache_body_model2 (e, "progs/b_g_key.mdl");
body_model (e, "progs/b_g_key.mdl");
}

if (e.keyname != "")
e.keyname = "";
else
e.netname = base_item_key_goldname ();

e.items = IT_KEY2;

// support for item_key_custom -- iw
e.customkeys = 0; // ignore any mapper-set value
e.noise = ""; // ignore any mapper-set value

// key_start
base_item_key_init (e);
};

//--------------------------------------------------------------
void() item_key2 =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

item_key2_init (self);
};
// };

//======================================================================
// item_key_custom is a brand-spanking-new entity class created for
// progs_dump -- iw
//======================================================================

/*QUAKED item_key_custom (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ({"path" : "progs/pd_w_key.mdl", "skin" : 1});
}
A customizable key item.

"keyname" name of the key, e.g. "bronze key" (required)
"mdl" model file (required)
"noise" sound file for the pickup sound (default is per worldtype)
"skin" skin index (default 0)

The "keyname" value is used both for the pickup message and to associate
the key with the entity that it unlocks.

To make a func_door or trigger_usekey require this key, set the
"keyname" value of that entity so that it matches the "keyname" value of
the key.

If different item_key_custom entities have the same "keyname" value,
they will be treated as different copies of the same key and may be used
interchangeably.

A map may have a maximum of 23 unique "keyname" values across all
entities.

The behavior of an item_key_custom should be as the player expects
(based on the behavior of the silver and gold keys), except for the fact
that it will not appear as an icon in the player's status bar when
picked up. This is a limitation of the engine.
*/
//----------------------------------------------------------------------
// class item_key_custom: base_item_key
// {
//--------------------------------------------------------------
entity(entity src, vector org, vector vel, string kname)
spawn_item_key_custom =
{
local entity e = spawn ();
e.owner = src;
e.origin = org;
e.velocity = vel;
e.keyname = kname;
item_key_custom_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) item_key_custom_init =
{
e.classname = "item_key_custom";
e.classtype = CT_ITEM_KEY_CUSTOM;
e.touch = base_item_key_touch;

if (e.keyname == "")
{
objerror ("no keyname specified");
return;
}

if (e.mdl == "")
{
objerror ("no mdl specified");
return;
}

precache_model (e.mdl);
setmodel (e, e.mdl);
// this should not be referenced again
e.mdl = "";

e.netname = e.keyname;
// this should not be referenced again
e.keyname = "";

// ignore any mapper-set value
e.items = 0;
e.customkeys = base_item_key_customflag (e.netname);

// key_start
base_item_key_init (e);
};

//--------------------------------------------------------------
void() item_key_custom =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

item_key_custom_init (self);
};
// };

Return to the top of this page or return to the overview of this repo.

Log keys.qc

Return to the top of this page or return to the overview of this repo.