doom 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/doom/game/animations.rb +97 -0
- data/lib/doom/game/combat.rb +244 -0
- data/lib/doom/game/item_pickup.rb +170 -0
- data/lib/doom/game/player_state.rb +101 -9
- data/lib/doom/game/sector_effects.rb +179 -0
- data/lib/doom/platform/gosu_window.rb +536 -66
- data/lib/doom/render/renderer.rb +297 -90
- data/lib/doom/render/status_bar.rb +74 -22
- data/lib/doom/render/weapon_renderer.rb +25 -28
- data/lib/doom/version.rb +1 -1
- data/lib/doom/wad/hud_graphics.rb +70 -2
- data/lib/doom/wad/sprite.rb +95 -22
- data/lib/doom/wad/texture.rb +23 -12
- data/lib/doom.rb +13 -2
- metadata +7 -6
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Doom
|
|
4
|
+
module Game
|
|
5
|
+
# Sector light specials and scrolling walls, matching Chocolate Doom's
|
|
6
|
+
# P_SpawnSpecials (p_spec.c) and p_lights.c.
|
|
7
|
+
class SectorEffects
|
|
8
|
+
GLOWSPEED = 8 # Light units per tic for glow
|
|
9
|
+
STROBEBRIGHT = 5 # Bright duration for strobes (tics)
|
|
10
|
+
FASTDARK = 15 # Dark duration for fast strobe (tics)
|
|
11
|
+
SLOWDARK = 35 # Dark duration for slow strobe (tics)
|
|
12
|
+
|
|
13
|
+
def initialize(map)
|
|
14
|
+
@map = map
|
|
15
|
+
@effects = []
|
|
16
|
+
@scroll_sides = []
|
|
17
|
+
spawn_specials
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Called every game tic (35/sec)
|
|
21
|
+
def update
|
|
22
|
+
@effects.each(&:update)
|
|
23
|
+
@scroll_sides.each { |side| side.x_offset += 1 }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def spawn_specials
|
|
29
|
+
@map.sectors.each do |sector|
|
|
30
|
+
case sector.special
|
|
31
|
+
when 1 # Flickering lights
|
|
32
|
+
@effects << LightFlash.new(sector, find_min_light(sector))
|
|
33
|
+
when 2 # Fast strobe
|
|
34
|
+
@effects << StrobeFlash.new(sector, find_min_light(sector), FASTDARK, false)
|
|
35
|
+
when 3 # Slow strobe
|
|
36
|
+
@effects << StrobeFlash.new(sector, find_min_light(sector), SLOWDARK, false)
|
|
37
|
+
when 4 # Fast strobe + 20% damage
|
|
38
|
+
@effects << StrobeFlash.new(sector, find_min_light(sector), FASTDARK, false)
|
|
39
|
+
when 8 # Glowing light
|
|
40
|
+
@effects << Glow.new(sector, find_min_light(sector))
|
|
41
|
+
when 12 # Sync strobe slow
|
|
42
|
+
@effects << StrobeFlash.new(sector, find_min_light(sector), SLOWDARK, true)
|
|
43
|
+
when 13 # Sync strobe fast
|
|
44
|
+
@effects << StrobeFlash.new(sector, find_min_light(sector), FASTDARK, true)
|
|
45
|
+
when 17 # Fire flicker
|
|
46
|
+
@effects << FireFlicker.new(sector, find_min_light(sector))
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Linedef type 48: scrolling wall (front side scrolls +1 unit/tic)
|
|
51
|
+
@map.linedefs.each do |linedef|
|
|
52
|
+
next unless linedef.special == 48
|
|
53
|
+
side = @map.sidedefs[linedef.sidedef_right]
|
|
54
|
+
@scroll_sides << side if side
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# P_FindMinSurroundingLight: find lowest light level among adjacent sectors
|
|
59
|
+
def find_min_light(sector)
|
|
60
|
+
min = sector.light_level
|
|
61
|
+
sector_idx = @map.sectors.index(sector)
|
|
62
|
+
return min unless sector_idx
|
|
63
|
+
|
|
64
|
+
@map.linedefs.each do |ld|
|
|
65
|
+
right = @map.sidedefs[ld.sidedef_right]
|
|
66
|
+
next unless right
|
|
67
|
+
left_idx = ld.sidedef_left
|
|
68
|
+
next if left_idx >= 0xFFFF
|
|
69
|
+
left = @map.sidedefs[left_idx]
|
|
70
|
+
next unless left
|
|
71
|
+
|
|
72
|
+
if right.sector == sector_idx && left.sector != sector_idx
|
|
73
|
+
other_light = @map.sectors[left.sector].light_level
|
|
74
|
+
min = other_light if other_light < min
|
|
75
|
+
elsif left.sector == sector_idx && right.sector != sector_idx
|
|
76
|
+
other_light = @map.sectors[right.sector].light_level
|
|
77
|
+
min = other_light if other_light < min
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
min
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# T_LightFlash (type 1): mostly bright with brief random dark flickers
|
|
84
|
+
class LightFlash
|
|
85
|
+
def initialize(sector, minlight)
|
|
86
|
+
@sector = sector
|
|
87
|
+
@maxlight = sector.light_level
|
|
88
|
+
@minlight = minlight
|
|
89
|
+
@count = (rand(65)) + 1
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def update
|
|
93
|
+
@count -= 1
|
|
94
|
+
return if @count > 0
|
|
95
|
+
|
|
96
|
+
if @sector.light_level == @maxlight
|
|
97
|
+
@sector.light_level = @minlight
|
|
98
|
+
@count = (rand(8)) + 1 # dark for 1-8 tics
|
|
99
|
+
else
|
|
100
|
+
@sector.light_level = @maxlight
|
|
101
|
+
@count = (rand(2) == 0 ? 1 : 65) # bright for 1 or 65 tics (P_Random()&64)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# T_StrobeFlash (types 2, 3, 4, 12, 13): regular strobe blink
|
|
107
|
+
class StrobeFlash
|
|
108
|
+
def initialize(sector, minlight, darktime, in_sync)
|
|
109
|
+
@sector = sector
|
|
110
|
+
@maxlight = sector.light_level
|
|
111
|
+
@minlight = minlight
|
|
112
|
+
@minlight = 0 if @minlight == @maxlight
|
|
113
|
+
@darktime = darktime
|
|
114
|
+
@brighttime = STROBEBRIGHT
|
|
115
|
+
@count = in_sync ? 1 : (rand(8)) + 1
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def update
|
|
119
|
+
@count -= 1
|
|
120
|
+
return if @count > 0
|
|
121
|
+
|
|
122
|
+
if @sector.light_level == @minlight
|
|
123
|
+
@sector.light_level = @maxlight
|
|
124
|
+
@count = @brighttime
|
|
125
|
+
else
|
|
126
|
+
@sector.light_level = @minlight
|
|
127
|
+
@count = @darktime
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# T_Glow (type 8): smooth triangle-wave oscillation
|
|
133
|
+
class Glow
|
|
134
|
+
def initialize(sector, minlight)
|
|
135
|
+
@sector = sector
|
|
136
|
+
@maxlight = sector.light_level
|
|
137
|
+
@minlight = minlight
|
|
138
|
+
@direction = -1 # start dimming
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def update
|
|
142
|
+
if @direction == -1
|
|
143
|
+
@sector.light_level -= GLOWSPEED
|
|
144
|
+
if @sector.light_level <= @minlight
|
|
145
|
+
@sector.light_level += GLOWSPEED
|
|
146
|
+
@direction = 1
|
|
147
|
+
end
|
|
148
|
+
else
|
|
149
|
+
@sector.light_level += GLOWSPEED
|
|
150
|
+
if @sector.light_level >= @maxlight
|
|
151
|
+
@sector.light_level -= GLOWSPEED
|
|
152
|
+
@direction = -1
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# T_FireFlicker (type 17): random fire-like flickering
|
|
159
|
+
class FireFlicker
|
|
160
|
+
def initialize(sector, minlight)
|
|
161
|
+
@sector = sector
|
|
162
|
+
@maxlight = sector.light_level
|
|
163
|
+
@minlight = minlight + 16 # fire doesn't go as dark
|
|
164
|
+
@count = 4
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def update
|
|
168
|
+
@count -= 1
|
|
169
|
+
return if @count > 0
|
|
170
|
+
|
|
171
|
+
amount = (rand(4)) * 16 # 0, 16, 32, or 48
|
|
172
|
+
level = @maxlight - amount
|
|
173
|
+
@sector.light_level = level < @minlight ? @minlight : level
|
|
174
|
+
@count = 4
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|