Xonotic
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:

Go to the source code of this file.

Functions

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

Variables

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

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  ,
BuildMutatorsString   
)

Definition at line 334 of file sv_random_items.qc.

References M_ARGV, and strcat().

335 {
336  M_ARGV(0, string) = strcat(M_ARGV(0, string), ":random_items");
337 }
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
#define M_ARGV(x, type)
Definition: events.qh:17
+ Here is the call graph for this function:

◆ MUTATOR_HOOKFUNCTION() [2/5]

MUTATOR_HOOKFUNCTION ( random_items  ,
BuildMutatorsPrettyString   
)

Definition at line 339 of file sv_random_items.qc.

References M_ARGV, and strcat().

340 {
341  M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Random items");
342 }
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
#define M_ARGV(x, type)
Definition: events.qh:17
+ Here is the call graph for this function:

◆ 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 345 of file sv_random_items.qc.

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

346 {
347  //PrintToChatAll("FilterItem");
349  {
350  return false;
351  }
352  if (random_items_is_spawning == true)
353  {
354  return false;
355  }
356  entity item = M_ARGV(0, entity);
357  if (Item_IsLoot(item))
358  {
359  return false;
360  }
361  if (RandomItems_ReplaceMapItem(item) == NULL)
362  {
363  return false;
364  }
365  return true;
366 }
entity() spawn
bool autocvar_g_random_items
Whether to enable random items.
#define NULL
Definition: post.qh:17
#define M_ARGV(x, type)
Definition: events.qh:17
bool Item_IsLoot(entity item)
Returns whether the item is loot.
Definition: spawning.qc:121
entity RandomItems_ReplaceMapItem(entity item)
Replaces a map item.
bool random_items_is_spawning
Probability of random s spawning as loot.
+ Here is the call graph for this function:

◆ 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 369 of file sv_random_items.qc.

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

370 {
371  //PrintToChatAll("ItemTouched");
373  {
374  return;
375  }
376  entity item = M_ARGV(0, entity);
377  if (Item_IsLoot(item))
378  {
379  return;
380  }
381  entity new_item = RandomItems_ReplaceMapItem(item);
382  if (new_item == NULL)
383  {
384  return;
385  }
386  Item_ScheduleRespawn(new_item);
387  delete(item);
388 }
entity() spawn
bool autocvar_g_random_items
Whether to enable random items.
#define NULL
Definition: post.qh:17
#define M_ARGV(x, type)
Definition: events.qh:17
bool Item_IsLoot(entity item)
Returns whether the item is loot.
Definition: spawning.qc:121
entity RandomItems_ReplaceMapItem(entity item)
Replaces a map item.
void Item_ScheduleRespawn(entity e)
Definition: items.qc:351
+ Here is the call graph for this function:

◆ MUTATOR_HOOKFUNCTION() [5/5]

MUTATOR_HOOKFUNCTION ( random_items  ,
PlayerDies   
)

Hook which is called when the player dies.

Definition at line 391 of file sv_random_items.qc.

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

392 {
393  //PrintToChatAll("PlayerDies");
395  {
396  return;
397  }
398  entity victim = M_ARGV(2, entity);
399  vector loot_position = victim.origin + '0 0 32';
400  int num_loot_items = floor(autocvar_g_random_loot_min + random() *
402  for (int item_index = 0; item_index < num_loot_items; ++item_index)
403  {
404  RandomItems_SpawnLootItem(loot_position);
405  }
406 }
float autocvar_g_random_loot_max
Maximum amount of loot items.
entity() spawn
float autocvar_g_random_loot_min
Classnames to replace s with.
void RandomItems_SpawnLootItem(vector position)
Spawns a random loot item.
#define M_ARGV(x, type)
Definition: events.qh:17
vector(float skel, float bonenum) _skel_get_boneabs_hidden
bool autocvar_g_random_loot
Whether to enable random loot.
+ Here is the call graph for this function:

◆ 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.

References cvar_string(), CVAR_TYPEFLAG_EXISTS, and LOG_WARNF.

Referenced by RandomItems_ReplaceMapItem().

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:67
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 gamemode and use cvars from that gamemode.

Definition at line 54 of file sv_random_items.qc.

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

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

55 {
57  {
58  return M_ARGV(1, string);
59  }
62 }
string RandomItems_GetRandomVanillaItemClassName(string prefix, int types)
Returns a random classname of the vanilla item.
string RandomItems_GetRandomItemClassName(string prefix)
Returns a random classname of the item.
#define M_ARGV(x, type)
Definition: events.qh:17
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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.

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().

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 is usable during normal gameplay.
Definition: item.qh:98
string RandomSelection_chosen_string
Definition: random.qh:7
bool Item_IsDefinitionAllowed(entity definition)
Checks whether the items with the specified definition are allowed to spawn.
Definition: spawning.qc:55
ERASEABLE void RandomSelection_Init()
Definition: random.qc:4
float CVAR_TYPEFLAG_EXISTS
#define RandomSelection_AddString(s, weight, priority)
Definition: random.qh:16
#define LOG_WARNF(...)
Definition: log.qh:67
#define FOREACH(list, cond, body)
Definition: iter.qh:19
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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.

References cvar(), CVAR_TYPEFLAG_EXISTS, FOREACH, 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(), and WEP_FLAG_MUTATORBLOCKED.

Referenced by RandomItems_GetRandomItemClassName().

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  {
83  RandomSelection_AddFloat(RANDOM_ITEM_TYPE_HEALTH,
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  {
96  RandomSelection_AddFloat(RANDOM_ITEM_TYPE_ARMOR,
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  {
109  RandomSelection_AddFloat(RANDOM_ITEM_TYPE_RESOURCE,
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  {
122  RandomSelection_AddFloat(RANDOM_ITEM_TYPE_WEAPON, cvar(cvar_name), 1);
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  {
134  RandomSelection_AddFloat(RANDOM_ITEM_TYPE_POWERUP, cvar(cvar_name), 1);
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  });
176  class_name = RandomSelection_chosen_string;
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 }
string RandomSelection_chosen_string
Definition: random.qh:7
ERASEABLE void RandomSelection_Init()
Definition: random.qc:4
float CVAR_TYPEFLAG_EXISTS
#define RandomSelection_AddString(s, weight, priority)
Definition: random.qh:16
float RandomSelection_chosen_float
Definition: random.qh:6
#define LOG_WARNF(...)
Definition: log.qh:67
string RandomItems_GetRandomItemClassNameWithProperty(string prefix,.bool item_property)
Returns a random classname of the item with specific property.
#define RandomSelection_AddFloat(f, weight, priority)
Definition: random.qh:15
const int WEP_FLAG_MUTATORBLOCKED
Definition: weapon.qh:203
#define FOREACH(list, cond, body)
Definition: iter.qh:19
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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.

References argv(), entity(), floor(), Item_Create(), Item_Initialize(), Item_ShouldKeepPosition(), MUTATOR_IS_ENABLED, NULL, random(), random_items_is_spawning, RandomItems_GetItemReplacementClassNames(), RandomItems_GetRandomItemClassName(), setorigin(), spawn(), strzone(), and tokenize_console.

Referenced by MUTATOR_HOOKFUNCTION().

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  entity new_item;
270  if (!MUTATOR_IS_ENABLED(ok))
271  {
272  new_item = Item_Create(strzone(new_classname), item.origin,
274  random_items_is_spawning = false;
275  if (new_item == NULL)
276  {
277  return NULL;
278  }
279  }
280  else
281  {
282  new_item = spawn();
283  new_item.classname = strzone(new_classname);
284  new_item.spawnfunc_checked = true;
285  new_item.noalign = Item_ShouldKeepPosition(item);
286  new_item.ok_item = true;
287  Item_Initialize(new_item, new_classname);
288  random_items_is_spawning = false;
289  if (wasfreed(new_item))
290  {
291  return NULL;
292  }
293  setorigin(new_item, item.origin);
294  }
295  if (item.team)
296  {
297  new_item.team = item.team;
298  }
299  return new_item;
300 }
string RandomItems_GetItemReplacementClassNames(entity item)
Returns list of classnames to replace a map item with.
void Item_Initialize(entity item, string class_name)
Initializes the item according to class name.
Definition: spawning.qc:75
entity() spawn
#define MUTATOR_IS_ENABLED(this)
Definition: base.qh:176
string RandomItems_GetRandomItemClassName(string prefix)
Returns a random classname of the item.
#define NULL
Definition: post.qh:17
#define tokenize_console
Definition: dpextensions.qh:24
bool Item_ShouldKeepPosition(entity item)
Returns whether item should keep its position or be dropped to the ground.
Definition: spawning.qc:131
entity Item_Create(string class_name, vector position, bool no_align)
Creates a new item.
Definition: spawning.qc:60
setorigin(ent, v)
bool random_items_is_spawning
Probability of random s spawning as loot.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RandomItems_SpawnLootItem()

void RandomItems_SpawnLootItem ( vector  position)

Spawns a random loot item.

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

Definition at line 305 of file sv_random_items.qc.

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

Referenced by MUTATOR_HOOKFUNCTION().

306 {
307  string class_name = RandomItems_GetRandomItemClassName("random_loot");
308  if (class_name == "")
309  {
310  return;
311  }
312  vector spread = '0 0 0';
313  spread.z = autocvar_g_random_loot_spread / 2;
316  if (!MUTATOR_IS_ENABLED(ok))
317  {
318  Item_CreateLoot(class_name, position, spread,
320  }
321  else
322  {
323  entity item = spawn();
324  item.ok_item = true;
325  item.classname = class_name;
326  Item_InitializeLoot(item, class_name, position, spread,
328  }
329  random_items_is_spawning = false;
330 }
float autocvar_g_random_loot_time
Amount of time the loot will stay.
bool Item_InitializeLoot(entity item, string class_name, vector position, vector vel, float time_to_live)
Initializes the loot item.
Definition: spawning.qc:101
entity() spawn
#define MUTATOR_IS_ENABLED(this)
Definition: base.qh:176
string RandomItems_GetRandomItemClassName(string prefix)
Returns a random classname of the item.
vector(float skel, float bonenum) _skel_get_boneabs_hidden
float autocvar_g_random_loot_spread
How far can loot be thrown.
bool random_items_is_spawning
Probability of random s spawning as loot.
entity Item_CreateLoot(string class_name, vector position, vector vel, float time_to_live)
Creates a loot item.
Definition: spawning.qc:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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().