Class: Doom::Game::SectorActions

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

Overview

Manages animated sector actions (doors, lifts, etc.)

Constant Summary collapse

DOOR_OPENING =

Door states (doors start at DOOR_OPENING and are deleted once fully closed, so there is no resting DOOR_CLOSED state to model).

1
DOOR_OPEN =
2
DOOR_CLOSING =
3
DOOR_SPEED =

Door speeds (units per tic, 35 tics/sec)

2
DOOR_WAIT =

Tics to wait when open (~4 seconds)

150
LIFT_SPEED =

Lift constants

4
LIFT_WAIT =

~3 seconds

105

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(map, sound_engine = nil) ⇒ SectorActions

Returns a new instance of SectorActions.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/doom/game/sector_actions.rb', line 35

def initialize(map, sound_engine = nil)
  @map = map
  @sound = sound_engine
  @active_doors = {}   # sector_index => door_state
  @active_lifts = {}   # sector_index => lift_state
  @player_x = 0
  @player_y = 0
  @player_positions = [] # [[player_id, x, y], ...] in id order
  @exit_triggered = nil
  @secrets_found = {}  # sector_index => true
  @crossed_linedefs = {}
  @near_linedefs = {}  # player_id => { linedef_idx => side }
  @teleport_dests = {} # player_id => { x:, y:, angle: }
end

Instance Attribute Details

#exit_triggeredObject (readonly)

Returns the value of attribute exit_triggered.



23
24
25
# File 'lib/doom/game/sector_actions.rb', line 23

def exit_triggered
  @exit_triggered
end

#secrets_foundObject (readonly)

Returns the value of attribute secrets_found.



23
24
25
# File 'lib/doom/game/sector_actions.rb', line 23

def secrets_found
  @secrets_found
end

Instance Method Details

#pop_teleportsObject

Pending teleports, drained by the world once per tic: a map of player_id => destination. Each player teleports to its own destination, so a single shared slot (which only ever moved player 0) is not enough in a multiplayer world.



29
30
31
32
33
# File 'lib/doom/game/sector_actions.rb', line 29

def pop_teleports
  dests = @teleport_dests
  @teleport_dests = {}
  dests
end

#updateObject



70
71
72
73
74
75
# File 'lib/doom/game/sector_actions.rb', line 70

def update
  update_doors
  update_lifts
  check_walk_triggers
  check_secrets
end

#update_player_position(x, y) ⇒ Object

Single-player convenience used by the unit specs and by the world's use-line ray cast: treat the given point as player 0's position.



52
53
54
55
56
# File 'lib/doom/game/sector_actions.rb', line 52

def update_player_position(x, y)
  @player_x = x
  @player_y = y
  @player_positions = [[0, x, y]]
end

#update_players(positions) ⇒ Object

Feed every player's position (ordered by id) so walk triggers fire for each player independently and reproducibly. The primary (first) position also drives the single-player-only checks (secrets, door reopen).



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

def update_players(positions)
  @player_positions = positions
  first = positions.first
  return unless first

  @player_x = first[1]
  @player_y = first[2]
end

#use_linedef(linedef, _linedef_idx, keys = {}) ⇒ Object

Try to use a linedef (called when player presses use key). keys is the acting player's key ring (a hash like true); locked doors consult it and refuse to open without the matching card.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/doom/game/sector_actions.rb', line 80

def use_linedef(linedef, _linedef_idx, keys = {})
  return false if linedef.special == 0

  case linedef.special
  # --- Doors ---
  when 1    # DR Door Open Wait Close
    activate_door(linedef)
  when 26   # DR Blue Door
    activate_door(linedef, key: :blue_card, keys: keys)
  when 27   # DR Yellow Door
    activate_door(linedef, key: :yellow_card, keys: keys)
  when 28   # DR Red Door
    activate_door(linedef, key: :red_card, keys: keys)
  when 31   # D1 Door Open Stay
    activate_door(linedef, stay_open: true)
  when 32   # D1 Blue Door Open Stay
    activate_door(linedef, key: :blue_card, stay_open: true, keys: keys)
  when 33   # D1 Red Door Open Stay
    activate_door(linedef, key: :red_card, stay_open: true, keys: keys)
  when 34   # D1 Yellow Door Open Stay
    activate_door(linedef, key: :yellow_card, stay_open: true, keys: keys)
  when 103  # S1 Door Open Wait Close (tagged)
    activate_tagged_door(linedef)

  # --- Lifts ---
  when 62 # SR Lift Lower Wait Raise (repeatable)
    activate_lift(linedef)

  # --- Floor changes ---
  when 18   # S1 Raise Floor to Next Higher
    raise_floor_to_next(linedef)
  when 20   # S1 Raise Floor to Next Higher (platform)
    raise_floor_to_next(linedef)
  when 22   # W1 Raise Floor to Next Higher
    raise_floor_to_next(linedef)
  when 23   # S1 Lower Floor to Lowest
    lower_floor_to_lowest(linedef)
  when 36   # S1 Lower Floor to Highest Adjacent - 8
    lower_floor_to_highest(linedef)
  when 70   # SR Lower Floor to Highest Adjacent - 8
    lower_floor_to_highest(linedef)

  # --- Exits ---
  when 11   # S1 Exit
    @exit_triggered = :normal
  when 51   # S1 Secret Exit
    @exit_triggered = :secret

  else
    return false
  end
  true
end