Class: Doom::Game::ItemPickup

Inherits:
Object
  • Object
show all
Defined in:
lib/doom/game/item_pickup.rb

Overview

Handles item pickup when player touches things. Matches Chocolate Doom's P_TouchSpecialThing from p_inter.c.

Constant Summary collapse

PLAYER_RADIUS =
16.0
THING_RADIUS =
20.0
PICKUP_DIST =

36 units (bounding box overlap)

PLAYER_RADIUS + THING_RADIUS
ITEMS =

Item definitions: type => { category, value, ... }

{
  # Weapons (give weapon + some ammo)
  2001 => { cat: :weapon, weapon: 2, ammo: :shells, amount: 8 },    # Shotgun
  2002 => { cat: :weapon, weapon: 3, ammo: :bullets, amount: 20 },  # Chaingun
  2003 => { cat: :weapon, weapon: 4, ammo: :rockets, amount: 2 },   # Rocket launcher
  2004 => { cat: :weapon, weapon: 5, ammo: :cells, amount: 40 },    # Plasma rifle
  2006 => { cat: :weapon, weapon: 6, ammo: :cells, amount: 40 },    # BFG9000
  2005 => { cat: :weapon, weapon: 7, ammo: :bullets, amount: 0 },   # Chainsaw

  # Ammo
  2007 => { cat: :ammo, ammo: :bullets, amount: 10 },   # Clip
  2048 => { cat: :ammo, ammo: :bullets, amount: 50 },   # Box of bullets
  2008 => { cat: :ammo, ammo: :shells, amount: 4 },     # 4 shells
  2049 => { cat: :ammo, ammo: :shells, amount: 20 },    # Box of shells
  2010 => { cat: :ammo, ammo: :rockets, amount: 1 },    # Rocket
  2046 => { cat: :ammo, ammo: :rockets, amount: 5 },    # Box of rockets
  17 => { cat: :ammo, ammo: :cells, amount: 20 }, # Cell charge
  2047 => { cat: :ammo, ammo: :cells, amount: 100 }, # Cell pack
  8 => { cat: :backpack }, # Backpack (doubles max ammo + some ammo)

  # Health
  2014 => { cat: :health, amount: 1, max: 200 },        # Health bonus (+1, up to 200)
  2011 => { cat: :health, amount: 10, max: 100 },       # Stimpack
  2012 => { cat: :health, amount: 25, max: 100 },       # Medikit
  2013 => { cat: :health, amount: 100, max: 200 },      # Soul sphere

  # Armor
  2015 => { cat: :armor, amount: 1, max: 200 }, # Armor bonus (+1, up to 200)
  2018 => { cat: :armor, amount: 100, armor_type: 1 },   # Green armor (100%, absorbs 1/3)
  2019 => { cat: :armor, amount: 200, armor_type: 2 },   # Blue armor (200%, absorbs 1/2)

  # Keys
  5 => { cat: :key, key: :blue_card },
  6 => { cat: :key, key: :yellow_card },
  13 => { cat: :key, key: :red_card },
  40 => { cat: :key, key: :blue_skull },
  39 => { cat: :key, key: :yellow_skull },
  38 => { cat: :key, key: :red_skull }
}.freeze
MESSAGETICS =

4 * TICRATE (4 seconds, matching Chocolate Doom)

140
FLASH_TICS =

Yellow palette flash duration

8
PICKUP_MESSAGES =
{
  2001 => 'A SHOTGUN!', 2002 => 'A CHAINGUN!', 2003 => 'A ROCKET LAUNCHER!',
  2004 => 'A PLASMA RIFLE!', 2005 => 'A CHAINSAW!', 2006 => 'A BFG9000!',
  2007 => 'PICKED UP A CLIP.', 2048 => 'PICKED UP A BOX OF BULLETS.',
  2008 => 'PICKED UP 4 SHOTGUN SHELLS.', 2049 => 'PICKED UP A BOX OF SHELLS.',
  2010 => 'PICKED UP A ROCKET.', 2046 => 'PICKED UP A BOX OF ROCKETS.',
  17 => 'PICKED UP AN ENERGY CELL.', 2047 => 'PICKED UP AN ENERGY CELL PACK.',
  8 => 'PICKED UP A BACKPACK FULL OF AMMO!',
  2011 => 'PICKED UP A STIMPACK.', 2012 => 'PICKED UP A MEDIKIT.',
  2014 => 'PICKED UP A HEALTH BONUS.', 2015 => 'PICKED UP AN ARMOR BONUS.',
  2018 => 'PICKED UP THE ARMOR.', 2019 => 'PICKED UP THE MEGAARMOR!',
  2013 => 'SUPERCHARGE!',
  5 => 'PICKED UP A BLUE KEYCARD.', 6 => 'PICKED UP A YELLOW KEYCARD.',
  13 => 'PICKED UP A RED KEYCARD.', 40 => 'PICKED UP A BLUE SKULL KEY.',
  39 => 'PICKED UP A YELLOW SKULL KEY.', 38 => 'PICKED UP A RED SKULL KEY.'
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(map, hidden_things = {}) ⇒ ItemPickup

Returns a new instance of ItemPickup.



59
60
61
62
63
64
65
66
67
# File 'lib/doom/game/item_pickup.rb', line 59

def initialize(map, hidden_things = {})
  @map = map
  @picked_up = {}
  @hidden_things = hidden_things
  @ammo_multiplier = 1
  @pickup_message = nil
  @pickup_flash = 0     # Yellow screen flash (short)
  @message_tics = 0     # Message display timer (long)
end

Instance Attribute Details

#ammo_multiplierObject

Returns the value of attribute ammo_multiplier.



57
58
59
# File 'lib/doom/game/item_pickup.rb', line 57

def ammo_multiplier
  @ammo_multiplier
end

#hidden_thingsObject

Returns the value of attribute hidden_things.



57
58
59
# File 'lib/doom/game/item_pickup.rb', line 57

def hidden_things
  @hidden_things
end

#message_ticsObject (readonly)

Returns the value of attribute message_tics.



56
57
58
# File 'lib/doom/game/item_pickup.rb', line 56

def message_tics
  @message_tics
end

#picked_upObject (readonly)

Returns the value of attribute picked_up.



56
57
58
# File 'lib/doom/game/item_pickup.rb', line 56

def picked_up
  @picked_up
end

#pickup_flashObject (readonly)

Returns the value of attribute pickup_flash.



56
57
58
# File 'lib/doom/game/item_pickup.rb', line 56

def pickup_flash
  @pickup_flash
end

#pickup_messageObject (readonly)

Returns the value of attribute pickup_message.



56
57
58
# File 'lib/doom/game/item_pickup.rb', line 56

def pickup_message
  @pickup_message
end

Instance Method Details

#update(player) ⇒ Object

Pick up for one player. picked_up stays global on purpose: in coop an item taken by anyone is gone for everyone, as in DOOM. Deathmatch respawning is a separate concern.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/doom/game/item_pickup.rb', line 78

def update(player)
  state = player.state
  @map.things.each_with_index do |thing, idx|
    next if @hidden_things[idx]
    next if @picked_up[idx]

    item = ITEMS[thing.type]
    next unless item

    dx = (player.x - thing.x).abs
    dy = (player.y - thing.y).abs
    next if dx >= PICKUP_DIST || dy >= PICKUP_DIST

    next unless try_pickup(item, state)

    @picked_up[idx] = true
    @pickup_message = PICKUP_MESSAGES[thing.type]
    @pickup_flash = FLASH_TICS
    @message_tics = MESSAGETICS
  end
end

#update_flashObject

Decay timers each tic



70
71
72
73
# File 'lib/doom/game/item_pickup.rb', line 70

def update_flash
  @pickup_flash -= 1 if @pickup_flash > 0
  @message_tics -= 1 if @message_tics > 0
end