diff --git a/code/game/g_cmds.c b/code/game/g_cmds.c index f349a1bc42..b8062193a3 100644 --- a/code/game/g_cmds.c +++ b/code/game/g_cmds.c @@ -318,7 +318,7 @@ void Cmd_Give_f (gentity_t *ent) it_ent = G_Spawn(); VectorCopy( ent->r.currentOrigin, it_ent->s.origin ); it_ent->classname = it->classname; - G_SpawnItem (it_ent, it); + G_SpawnItem (it_ent, it, qtrue); FinishSpawningItem(it_ent ); memset( &trace, 0, sizeof( trace ) ); Touch_Item (it_ent, ent, &trace); diff --git a/code/game/g_items.c b/code/game/g_items.c index 6cb31aa427..393e73fcd2 100644 --- a/code/game/g_items.c +++ b/code/game/g_items.c @@ -363,15 +363,33 @@ void RespawnItem( gentity_t *ent ) { } master = ent->teammaster; - for (count = 0, ent = master; ent; ent = ent->teamchain, count++) - ; + for (count = 0, ent = master; ent; ent = ent->teamchain) { + // Skip disabled (possibly through a disable_%s cvar) items + if ( !ent->item ) { + continue; + } + + count++; + } + + // No valid items to spawn + if ( count == 0 ) { + return; + } choice = rand() % count; - for (count = 0, ent = master; ent && count < choice; ent = ent->teamchain, count++) - ; + for (count = 0, ent = master; ent && count < choice; ent = ent->teamchain) { + // Skip disabled (possibly through a disable_%s cvar) items + if ( !ent->item ) { + continue; + } + + count++; + } } + // ent->item should not be nullish to this time if (!ent) { return; } @@ -883,14 +901,18 @@ Sets the clipping size and plants the object on the floor. Items can't be immediately dropped to floor, because they might be on an entity that hasn't spawned yet. + +forceSpawn lets to bypass check for disabled through disable_%s +cvar items and spawn them anyway. Used for spawning items through +third party sources like give command. ============ */ -void G_SpawnItem (gentity_t *ent, gitem_t *item) { +void G_SpawnItem (gentity_t *ent, gitem_t *item, qboolean forceSpawn) { G_SpawnFloat( "random", "0", &ent->random ); G_SpawnFloat( "wait", "0", &ent->wait ); RegisterItem( item ); - if ( G_ItemDisabled(item) ) + if ( !forceSpawn && G_ItemDisabled(item) ) return; ent->item = item; diff --git a/code/game/g_local.h b/code/game/g_local.h index 10ec8dbf44..ee0ac972f5 100644 --- a/code/game/g_local.h +++ b/code/game/g_local.h @@ -442,7 +442,7 @@ void PrecacheItem (gitem_t *it); gentity_t *Drop_Item( gentity_t *ent, gitem_t *item, float angle ); gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity ); void SetRespawn (gentity_t *ent, float delay); -void G_SpawnItem (gentity_t *ent, gitem_t *item); +void G_SpawnItem (gentity_t *ent, gitem_t *item, qboolean forceSpawn); void FinishSpawningItem( gentity_t *ent ); void Think_Weapon (gentity_t *ent); int ArmorIndex (gentity_t *ent); diff --git a/code/game/g_spawn.c b/code/game/g_spawn.c index a34ced5f07..b502fbd93c 100644 --- a/code/game/g_spawn.c +++ b/code/game/g_spawn.c @@ -277,7 +277,7 @@ qboolean G_CallSpawn( gentity_t *ent ) { // check item spawn functions for ( item=bg_itemlist+1 ; item->classname ; item++ ) { if ( !strcmp(item->classname, ent->classname) ) { - G_SpawnItem( ent, item ); + G_SpawnItem( ent, item, qfalse ); return qtrue; } }