Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
sv_random_items.qc File Reference

Source file that contains implementation of the random items mutator. More...

#include "sv_random_items.qh"
Include dependency graph for sv_random_items.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

 MUTATOR_HOOKFUNCTION (random_items, BuildMutatorsPrettyString)
 MUTATOR_HOOKFUNCTION (random_items, BuildMutatorsString)
 MUTATOR_HOOKFUNCTION (random_items, FilterItem, CBC_ORDER_LAST)
 Hook that is called when an item is about to spawn.
 MUTATOR_HOOKFUNCTION (random_items, ItemTouched, CBC_ORDER_LAST)
 Hook that is called after the player has touched an item.
 MUTATOR_HOOKFUNCTION (random_items, PlayerDies)
 Hook which is called when the player dies.
string RandomItems_GetItemReplacementClassNames (entity item)
 Returns list of classnames to replace a map item with.
string RandomItems_GetRandomItemClassName (string prefix)
 Returns a random classname of the item.
string RandomItems_GetRandomItemClassNameWithProperty (string prefix,.bool item_property)
 Returns a random classname of the item with specific property.
string RandomItems_GetRandomVanillaItemClassName (string prefix, int types)
 Returns a random classname of the vanilla item.
entity RandomItems_ReplaceMapItem (entity item)
 Replaces a map item.
void RandomItems_SpawnLootItem (vector position)
 Spawns a random loot item.

Variables

float autocvar_g_random_loot_max
 Maximum amount of loot items.
float autocvar_g_random_loot_min
 Classnames to replace s with.
float autocvar_g_random_loot_spread
 How far can loot be thrown.
float autocvar_g_random_loot_time
 Amount of time the loot will stay.
bool random_items_is_spawning = false
 Probability of random s spawning as loot.

Detailed Description

Source file that contains implementation of the random items mutator.

Author
Lyberta

Definition in file sv_random_items.qc.

Function Documentation

◆ MUTATOR_HOOKFUNCTION() [1/5]

MUTATOR_HOOKFUNCTION ( random_items ,
BuildMutatorsPrettyString  )

Definition at line 317 of file sv_random_items.qc.

318{
319 M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Random items");
320}
#define M_ARGV(x, type)
Definition events.qh:17
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))

References M_ARGV, and strcat().

◆ MUTATOR_HOOKFUNCTION() [2/5]

MUTATOR_HOOKFUNCTION ( random_items ,
BuildMutatorsString  )

Definition at line 312 of file sv_random_items.qc.

313{
314 M_ARGV(0, string) = strcat(M_ARGV(0, string), ":random_items");
315}

References M_ARGV, and strcat().

◆ MUTATOR_HOOKFUNCTION() [3/5]

MUTATOR_HOOKFUNCTION ( random_items ,
FilterItem ,
CBC_ORDER_LAST  )

Hook that is called when an item is about to spawn.

Definition at line 323 of file sv_random_items.qc.

324{
325 //PrintToChatAll("FilterItem");
327 {
328 return false;
329 }
330 if (random_items_is_spawning == true)
331 {
332 return false;
333 }
334 entity item = M_ARGV(0, entity);
335 if (ITEM_IS_LOOT(item))
336 {
337 return false;
338 }
339 if (RandomItems_ReplaceMapItem(item) == NULL)
340 {
341 return false;
342 }
343 return true;
344}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define ITEM_IS_LOOT(item)
Returns whether the item is loot.
Definition spawning.qh:39
#define NULL
Definition post.qh:14
entity RandomItems_ReplaceMapItem(entity item)
Replaces a map item.
bool random_items_is_spawning
Probability of random s spawning as loot.
bool autocvar_g_random_items
Whether to enable random items.

References autocvar_g_random_items, CBC_ORDER_LAST, entity(), ITEM_IS_LOOT, M_ARGV, NULL, random_items_is_spawning, and RandomItems_ReplaceMapItem().

◆ MUTATOR_HOOKFUNCTION() [4/5]

MUTATOR_HOOKFUNCTION ( random_items ,
ItemTouched ,
CBC_ORDER_LAST  )

Hook that is called after the player has touched an item.

Definition at line 347 of file sv_random_items.qc.

348{
349 //PrintToChatAll("ItemTouched");
351 {
352 return;
353 }
354 entity item = M_ARGV(0, entity);
355 if (ITEM_IS_LOOT(item))
356 {
357 return;
358 }
359 entity new_item = RandomItems_ReplaceMapItem(item);
360 if (new_item == NULL)
361 {
362 return;
363 }
364 Item_ScheduleRespawn(new_item);
365 delete(item);
366}
void Item_ScheduleRespawn(entity e)
Definition items.qc:391

References autocvar_g_random_items, CBC_ORDER_LAST, entity(), ITEM_IS_LOOT, Item_ScheduleRespawn(), M_ARGV, NULL, and RandomItems_ReplaceMapItem().

◆ MUTATOR_HOOKFUNCTION() [5/5]

MUTATOR_HOOKFUNCTION ( random_items ,
PlayerDies  )

Hook which is called when the player dies.

Definition at line 369 of file sv_random_items.qc.

370{
371 //PrintToChatAll("PlayerDies");
373 {
374 return;
375 }
376 entity victim = M_ARGV(2, entity);
377 vector loot_position = victim.origin + '0 0 32';
378 int num_loot_items = floor(autocvar_g_random_loot_min + random() *
380 for (int item_index = 0; item_index < num_loot_items; ++item_index)
381 {
382 RandomItems_SpawnLootItem(loot_position);
383 }
384}
float random(void)
float floor(float f)
vector
Definition self.qh:92
float autocvar_g_random_loot_min
Classnames to replace s with.
float autocvar_g_random_loot_max
Maximum amount of loot items.
void RandomItems_SpawnLootItem(vector position)
Spawns a random loot item.
bool autocvar_g_random_loot
Whether to enable random loot.

References autocvar_g_random_loot, autocvar_g_random_loot_max, autocvar_g_random_loot_min, entity(), floor(), M_ARGV, random(), RandomItems_SpawnLootItem(), and vector.

◆ RandomItems_GetItemReplacementClassNames()

string RandomItems_GetItemReplacementClassNames ( entity item)

Returns list of classnames to replace a map item with.

Parameters
[in]itemItem to inspect.
Returns
List of classnames to replace a map item with.

Definition at line 200 of file sv_random_items.qc.

201{
202 string cvar_name = sprintf("g_random_items_replace_%s", item.classname);
203 if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
204 {
205 LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
206 return "";
207 }
208 return cvar_string(cvar_name);
209}
float CVAR_TYPEFLAG_EXISTS
#define LOG_WARNF(...)
Definition log.qh:62
const string cvar_string(string name)

References cvar_string(), CVAR_TYPEFLAG_EXISTS, entity(), and LOG_WARNF.

Referenced by RandomItems_ReplaceMapItem().

◆ RandomItems_GetRandomItemClassName()

string RandomItems_GetRandomItemClassName ( string prefix)

Returns a random classname of the item.

Parameters
[in]prefixPrefix of the cvars that hold probabilities.
Returns
Random classname of the item.
Note
This function will automatically detect gametype and use cvars from that gametype.

Definition at line 54 of file sv_random_items.qc.

55{
57 {
58 return M_ARGV(1, string);
59 }
62}
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
string RandomItems_GetRandomItemClassName(string prefix)
Returns a random classname of the item.
string RandomItems_GetRandomVanillaItemClassName(string prefix, int types)
Returns a random classname of the vanilla item.
@ RANDOM_ITEM_TYPE_ALL

References M_ARGV, MUTATOR_CALLHOOK, RANDOM_ITEM_TYPE_ALL, RandomItems_GetRandomItemClassName(), and RandomItems_GetRandomVanillaItemClassName().

Referenced by MUTATOR_HOOKABLE(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), RandomItems_GetRandomItemClassName(), RandomItems_ReplaceMapItem(), and RandomItems_SpawnLootItem().

◆ RandomItems_GetRandomItemClassNameWithProperty()

string RandomItems_GetRandomItemClassNameWithProperty ( string prefix,
.bool item_property )

Returns a random classname of the item with specific property.

Parameters
[in]prefixPrefix of the cvars that hold probabilities.
Returns
Random classname of the item.

Definition at line 211 of file sv_random_items.qc.

213{
215 FOREACH(Items, it.item_property && (it.spawnflags & ITEM_FLAG_NORMAL) &&
217 {
218 string cvar_name = sprintf("g_%s_%s_probability", prefix,
219 it.m_canonical_spawnfunc);
220 if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
221 {
222 LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
223 continue;
224 }
225 RandomSelection_AddString(it.m_canonical_spawnfunc, cvar(cvar_name), 1);
226 });
228}
@ ITEM_FLAG_NORMAL
Item is usable during normal gameplay.
Definition item.qh:120
bool Item_IsDefinitionAllowed(entity definition)
Checks whether the items with the specified definition are allowed to spawn.
Definition spawning.qc:17
#define FOREACH(list, cond, body)
Definition iter.qh:19
float cvar(string name)
ERASEABLE void RandomSelection_Init()
Definition random.qc:4
string RandomSelection_chosen_string
Definition random.qh:7
#define RandomSelection_AddString(s, weight, priority)
Definition random.qh:16

References cvar(), CVAR_TYPEFLAG_EXISTS, FOREACH, ITEM_FLAG_NORMAL, Item_IsDefinitionAllowed(), LOG_WARNF, RandomSelection_AddString, RandomSelection_chosen_string, and RandomSelection_Init().

Referenced by RandomItems_GetRandomVanillaItemClassName().

◆ RandomItems_GetRandomVanillaItemClassName()

string RandomItems_GetRandomVanillaItemClassName ( string prefix,
int types )

Returns a random classname of the vanilla item.

Parameters
[in]prefixPrefix of the cvars that hold probabilities.
[in]typesBitmask of the types. See RANDOM_ITEM_TYPE constants.
Returns
Random classname of the vanilla item.
Note
This includes mutator items that don't change gameplay a lot such as jetpack and new toys.

Definition at line 64 of file sv_random_items.qc.

65{
66 if (types == 0)
67 {
68 return "";
69 }
70 while (types != 0)
71 {
72 string cvar_name;
74 if (types & RANDOM_ITEM_TYPE_HEALTH)
75 {
76 cvar_name = sprintf("g_%s_health_probability", prefix);
77 if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
78 {
79 LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
80 }
81 else
82 {
84 cvar(cvar_name), 1);
85 }
86 }
87 if (types & RANDOM_ITEM_TYPE_ARMOR)
88 {
89 cvar_name = sprintf("g_%s_armor_probability", prefix);
90 if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
91 {
92 LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
93 }
94 else
95 {
97 cvar(cvar_name), 1);
98 }
99 }
100 if (types & RANDOM_ITEM_TYPE_RESOURCE)
101 {
102 cvar_name = sprintf("g_%s_resource_probability", prefix);
103 if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
104 {
105 LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
106 }
107 else
108 {
110 cvar(cvar_name), 1);
111 }
112 }
113 if (types & RANDOM_ITEM_TYPE_WEAPON)
114 {
115 cvar_name = sprintf("g_%s_weapon_probability", prefix);
116 if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
117 {
118 LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
119 }
120 else
121 {
123 }
124 }
125 if (types & RANDOM_ITEM_TYPE_POWERUP)
126 {
127 cvar_name = sprintf("g_%s_powerup_probability", prefix);
128 if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
129 {
130 LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
131 }
132 else
133 {
135 }
136 }
137 int item_type = RandomSelection_chosen_float;
138 string class_name = "";
139 switch (item_type)
140 {
142 {
144 prefix, instanceOfHealth);
145 break;
146 }
148 {
150 prefix, instanceOfArmor);
151 break;
152 }
154 {
156 prefix, instanceOfAmmo);
157 break;
158 }
160 {
162 FOREACH(Weapons, it != WEP_Null &&
163 !(it.spawnflags & WEP_FLAG_MUTATORBLOCKED),
164 {
165 cvar_name = sprintf("g_%s_%s_probability", prefix,
166 it.m_canonical_spawnfunc);
167 if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
168 {
169 LOG_WARNF("Random items: cvar %s doesn't exist.",
170 cvar_name);
171 continue;
172 }
173 RandomSelection_AddString(it.m_canonical_spawnfunc,
174 cvar(cvar_name), 1);
175 });
177 break;
178 }
180 {
182 prefix, instanceOfPowerup);
183 break;
184 }
185 }
186 if (class_name != "")
187 {
188 return class_name;
189 }
190 types &= ~item_type;
191 }
192 return "";
193}
Weapons
Definition guide.qh:113
bool instanceOfAmmo
Definition guide.qh:30
bool instanceOfPowerup
Definition guide.qh:33
bool instanceOfHealth
Definition guide.qh:31
bool instanceOfArmor
Definition guide.qh:32
float RandomSelection_chosen_float
Definition random.qh:6
#define RandomSelection_AddFloat(f, weight, priority)
Definition random.qh:15
string RandomItems_GetRandomItemClassNameWithProperty(string prefix,.bool item_property)
Returns a random classname of the item with specific property.
@ RANDOM_ITEM_TYPE_RESOURCE
@ RANDOM_ITEM_TYPE_HEALTH
@ RANDOM_ITEM_TYPE_WEAPON
@ RANDOM_ITEM_TYPE_ARMOR
@ RANDOM_ITEM_TYPE_POWERUP
const int WEP_FLAG_MUTATORBLOCKED
Definition weapon.qh:219

References cvar(), CVAR_TYPEFLAG_EXISTS, FOREACH, instanceOfAmmo, instanceOfArmor, instanceOfHealth, instanceOfPowerup, LOG_WARNF, RANDOM_ITEM_TYPE_ARMOR, RANDOM_ITEM_TYPE_HEALTH, RANDOM_ITEM_TYPE_POWERUP, RANDOM_ITEM_TYPE_RESOURCE, RANDOM_ITEM_TYPE_WEAPON, RandomItems_GetRandomItemClassNameWithProperty(), RandomSelection_AddFloat, RandomSelection_AddString, RandomSelection_chosen_float, RandomSelection_chosen_string, RandomSelection_Init(), Weapons, and WEP_FLAG_MUTATORBLOCKED.

Referenced by RandomItems_GetRandomItemClassName().

◆ RandomItems_ReplaceMapItem()

entity RandomItems_ReplaceMapItem ( entity item)

Replaces a map item.

Parameters
[in]itemItem to replace.
Returns
Spawned item on success, NULL otherwise.

Definition at line 233 of file sv_random_items.qc.

234{
235 //PrintToChatAll(strcat("Replacing ", item.classname));
236 string new_classnames = RandomItems_GetItemReplacementClassNames(item);
237 if (new_classnames == "")
238 {
239 return NULL;
240 }
241 string new_classname;
242 if (new_classnames == "random")
243 {
244 new_classname = RandomItems_GetRandomItemClassName("random_items");
245 if (new_classname == "")
246 {
247 return NULL;
248 }
249 }
250 else
251 {
252 int num_new_classnames = tokenize_console(new_classnames);
253 if (num_new_classnames == 1)
254 {
255 new_classname = new_classnames;
256 }
257 else
258 {
259 int classname_index = floor(random() * num_new_classnames);
260 new_classname = argv(classname_index);
261 }
262 }
263 //PrintToChatAll(strcat("Replacing with ", new_classname));
264 if (new_classname == item.classname)
265 {
266 return NULL;
267 }
269
270 entity new_item = spawn();
271 Item_CopyFields(item, new_item);
272 new_item.classname = strzone(new_classname);
273 new_item.lifetime = -1; // permanent (not loot)
274 if (MUTATOR_IS_ENABLED(ok))
275 new_item.ok_item = true;
276 Item_Initialise(new_item);
277
279
280 return wasfreed(new_item) ? NULL : new_item;
281}
#define MUTATOR_IS_ENABLED(this)
Definition base.qh:193
#define spawn
#define tokenize_console
bool Item_Initialise(entity item)
An optimised and generic way to initialise items (loot or permanent)
Definition spawning.qc:27
string strzone(string s)
string argv(float n)
void Item_CopyFields(entity this, entity to)
Definition items.qc:850
string RandomItems_GetItemReplacementClassNames(entity item)
Returns list of classnames to replace a map item with.

References argv(), entity(), floor(), Item_CopyFields(), Item_Initialise(), MUTATOR_IS_ENABLED, NULL, random(), random_items_is_spawning, RandomItems_GetItemReplacementClassNames(), RandomItems_GetRandomItemClassName(), spawn, strzone(), and tokenize_console.

Referenced by MUTATOR_HOOKFUNCTION(), and MUTATOR_HOOKFUNCTION().

◆ RandomItems_SpawnLootItem()

void RandomItems_SpawnLootItem ( vector position)

Spawns a random loot item.

Parameters
[in]positionPosition of the item.
Returns
No return.

Definition at line 286 of file sv_random_items.qc.

287{
288 string class_name = RandomItems_GetRandomItemClassName("random_loot");
289 if (class_name == "")
290 {
291 return;
292 }
293 vector spread = '0 0 0';
294 spread.z = autocvar_g_random_loot_spread / 2;
297
298 entity item = spawn();
299 item.classname = class_name;
300 item.origin = position;
301 item.velocity = spread;
302 item.lifetime = autocvar_g_random_loot_time;
303 if (MUTATOR_IS_ENABLED(ok))
304 item.ok_item = true;
305 Item_Initialise(item);
306
308}
vector randomvec(void)
float autocvar_g_random_loot_time
Amount of time the loot will stay.
float autocvar_g_random_loot_spread
How far can loot be thrown.

References autocvar_g_random_loot_spread, autocvar_g_random_loot_time, entity(), Item_Initialise(), MUTATOR_IS_ENABLED, random_items_is_spawning, RandomItems_GetRandomItemClassName(), randomvec(), spawn, and vector.

Referenced by MUTATOR_HOOKFUNCTION().

Variable Documentation

◆ autocvar_g_random_loot_max

float autocvar_g_random_loot_max

Maximum amount of loot items.

Definition at line 28 of file sv_random_items.qc.

Referenced by MUTATOR_HOOKFUNCTION().

◆ autocvar_g_random_loot_min

float autocvar_g_random_loot_min

Classnames to replace s with.

string autocvar_g_random_items_replace_s;

Probability of random s spawning in the map. float autocvar_g_random_items_s_probability;

Probability of random s spawning in the map during overkill. float autocvar_g_random_items_overkill_s_probability; Minimum amount of loot items.

Definition at line 27 of file sv_random_items.qc.

Referenced by MUTATOR_HOOKFUNCTION().

◆ autocvar_g_random_loot_spread

float autocvar_g_random_loot_spread

How far can loot be thrown.

Definition at line 30 of file sv_random_items.qc.

Referenced by RandomItems_SpawnLootItem().

◆ autocvar_g_random_loot_time

float autocvar_g_random_loot_time

Amount of time the loot will stay.

Definition at line 29 of file sv_random_items.qc.

Referenced by RandomItems_SpawnLootItem().

◆ random_items_is_spawning

bool random_items_is_spawning = false

Probability of random s spawning as loot.

float autocvar_g_random_loot_s_probability;

Probability of random s spawning as loot during overkill. float autocvar_g_random_loot_overkill_s_probability;

Holds whether random item is spawning. Used to prevent infinite recursion.

Definition at line 42 of file sv_random_items.qc.

Referenced by MUTATOR_HOOKFUNCTION(), RandomItems_ReplaceMapItem(), and RandomItems_SpawnLootItem().