Weapon pickup
An item that changes the player's gun when touched.
On this page
A weapon pickup changes the gun the player fires. In Contra and Super C a touched item dispatches on its type: four guns replace the one held, R adds rapid fire, B gives a spell of invincibility, and the falcon destroys the enemies on screen1,2. The two differ on rapid fire. Contra keeps it when the new gun is the one already held, and Super C drops it on any gun2. Quake II keeps every gun taken, adding its ammo, and switches to a new one only the first time3.
- ReplaceContra (1987). Falcons carry M, F, S, L, R, B, or a screen-clearing falcon; a new gun drops rapid fire unless it's the one held.1Super C (1990). Contra's seven item types, but a new gun always drops rapid fire.2
- InventoryQuake II (1997). Every weapon taken stays in the inventory with its ammo; the player switches only to a new one, and in deathmatch only from the blaster.3
Games
| Game | Year | How | Note |
|---|---|---|---|
| Contra | 1987 | Replace | falcons carry M, F, S, L, R, B, or a screen-clearing falcon; a new gun drops rapid fire unless it's the one held |
| Super C | 1990 | Replace | Contra's seven item types, but a new gun always drops rapid fire |
| Quake II | 1997 | Inventory | every weapon taken stays in the inventory with its ammo; the player switches only to a new one, and in deathmatch only from the blaster |
Every claim about this mechanic, by game (3)
References
- ^ abTouching a weapon item in the US NES Contra adds 1,000 points and dispatches on the item's type: R sets the rapid-fire bit, M, F, S, and L replace the gun (keeping rapid fire only when the new gun is the one held), B starts an invincibility timer at
$80($90on level 7), and the falcon destroys the enemies on screen. A death resets the gun to the default.Codevermiceli/nes-contra-usHow we know
6884pick_up_weapon_item: ⋮ 6886 lda #$0a ; a = #$0a 6887 sta $00 ; set score to add to player as #$0a (1,000 points) ⋮ 6895 lda ENEMY_ATTRIBUTES,y ; get weapon item attributes 6896 and #$07 ; keep bits 0-2 (attributes) 6897 beq @set_rapid_flag ; set rapid flag for weapon if attribute is #$00 6898 cmp #$05 ; check for b weapon (barrier). Gives invincibility 6899 bcc @compare_and_set_weapon ; branch if less than #$05 (MFSL) 6900 beq @set_invincibility_timer ; branch for barrier weapon 6901 jsr destroy_all_enemies ; falcon weapon effect - destroy all enemies ⋮ 6912@set_invincibility_timer: 6913 lda #$80 ; set duration of the b weapon effect ⋮
src/bank7.asm lines 6884–6955 at 687d651 · upstream ↗ 5150init_player_dec_num_lives: 5151 jsr init_player_and_weapon ; initialize player variables to 0
src/bank7.asm lines 5150–5151 at 687d651 · upstream ↗ 5338init_player_and_weapon: 5339 lda #$00 ; a = #$00 5340 sta P1_CURRENT_WEAPON,x ; reset current player's weapon
src/bank7.asm lines 5338–5340 at 687d651 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abcThe US NES Super C dispatches a weapon item on its type: M, S, L, and F replace the gun, R sets rapid fire, B sets an invincibility timer to
$80, and the falcon destroys the enemies. A new gun drops rapid fire even when it's the gun already held, where Contra keeps it for the same gun.Codevermiceli/nes-super-c · vermiceli/nes-contra-usrevisedHow we know
411weapon_item_pickup_tbl: 412 .addr weapon_item_pickup ; machine (M) 413 .addr weapon_item_pickup ; spray (S) 414 .addr weapon_item_pickup ; laser (L) 415 .addr weapon_item_pickup ; flame (F) 416 .addr r_weapon_item_pickup ; rapid fire (R) 417 .addr b_weapon_item_pickup ; barrier (B) 418 .addr falcon_weapon_item_pickup ; falcon ⋮ 422 lda #$80 423 sta INVINCIBILITY_TIMER,y ; set player invincible timer to #$80 frames ⋮ 428 jsr destroy_all_enemies ; destroy all appropriate enemies ⋮ 431r_weapon_item_pickup: ⋮
src/bank-3.asm lines 411–445 at be6ccce · upstream ↗ 6933@compare_and_set_weapon: 6934 ldy #$f0 ; y = #$f0 (keep rapid fire flag) ⋮ 6938 beq @set_player_weapon ; keep rapid fire flag (if set) when picking up same weapon 6939 ldy #$e0 ; remove rapid fire flag since picking up different weapon ⋮ 6943 and P1_CURRENT_WEAPON,x ; strip/set rapid fire flag 6944 ora $08 ; merge in rapid fire flag with weapon being picked up 6945 sta P1_CURRENT_WEAPON,x ; set current player's weapon
src/bank7.asm lines 6933–6945 at 687d651 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^ abA Quake II weapon pickup adds the weapon to the player's inventory, which keeps every weapon taken, and gives that weapon's ammo with it unless the item carries the
DROPPED_ITEMflag. The player switches to it only when it is the first of its kind carried, and in deathmatch only while the blaster is in hand. In coop, or in deathmatch with weapons-stay set, a player who already has the weapon can't take a placed one. A placed weapon picked up in deathmatch stays where it is with weapons-stay set and otherwise respawns after 30 seconds, and in coop it stays; a weapon flaggedDROPPED_PLAYER_ITEM, which a dying player's weapon is, gives its ammo but neither stays nor respawns.Codeid-Software/Quake-2revisedHow we know
125 if ( ( ((int)(dmflags->value) & DF_WEAPONS_STAY) || coop->value) 126 && other->client->pers.inventory[index]) ⋮ 128 if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM) ) ) 129 return false; // leave the weapon for others to pickup ⋮ 132 other->client->pers.inventory[index]++; ⋮ 134 if (!(ent->spawnflags & DROPPED_ITEM) ) ⋮ 136 // give them some ammo with it 137 ammo = FindItem (ent->item->ammo); ⋮ 140 else 141 Add_Ammo (other, ammo, ammo->quantity); ⋮ 143 if (! (ent->spawnflags & DROPPED_PLAYER_ITEM) ) ⋮ 145 if (deathmatch->value) ⋮
game/p_weapon.c lines 125–160 at 372afde · upstream ↗ 814 if (!((coop->value) && (ent->item->flags & IT_STAY_COOP)) || (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM))) ⋮ 816 if (ent->flags & FL_RESPAWN) 817 ent->flags &= ~FL_RESPAWN; 818 else 819 G_FreeEdict (ent);
game/g_items.c lines 814–819 at 372afde · upstream ↗ 439 drop = Drop_Item (self, item); ⋮ 441 drop->spawnflags = DROPPED_PLAYER_ITEM;
game/p_client.c lines 439–441 at 372afde · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
Sources
Code
- (vermiceli), Michael Miceli. 2026. “Contra (US), annotated disassembly (vermiceli).” Commit 687d651. vermiceli/nes-contra-us @ 687d651 · licence, all uses
- (vermiceli), Michael Miceli. 2026. “Super C (US), annotated disassembly (vermiceli).” Commit be6ccce. vermiceli/nes-super-c @ be6ccce · licence, all uses
- Software, id. 2012. “Quake II: the GPL source release (id-Software/Quake-2, 3.19).” Commit 372afde. id-Software/Quake-2 @ 372afde · licence, all uses