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, player_state, hidden_things = {}) ⇒ ItemPickup

Returns a new instance of ItemPickup.



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

def initialize(map, player_state, hidden_things = {})
  @map = map
  @player = player_state
  @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_x, player_y) ⇒ Object



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

def update(player_x, player_y)
  @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

    if try_pickup(item)
      @picked_up[idx] = true
      @pickup_message = PICKUP_MESSAGES[thing.type]
      @pickup_flash = FLASH_TICS
      @message_tics = MESSAGETICS
    end
  end
end

#update_flashObject

Decay timers each tic



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

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