Class: Quake::Debug::Script
- Inherits:
-
Object
- Object
- Quake::Debug::Script
- Defined in:
- lib/quake/debug/script.rb
Overview
DSL for scripting headless game runs.
Example script.rb:
load_map "maps/e1m1.bsp"
teleport 480, 600, 96, yaw: 90
ticks 30
screenshot "shots/start.png"
hold :w
ticks 60 # 1 second forward
release :w
ticks 30
screenshot "shots/forward.png"
dump_state
Constant Summary collapse
- DEFAULT_DT =
1.0 / 60.0
- KEY_MAP =
{ w: SDL::SCANCODE_W, a: SDL::SCANCODE_A, s: SDL::SCANCODE_S, d: SDL::SCANCODE_D, space: SDL::SCANCODE_SPACE, ctrl: SDL::SCANCODE_LCTRL, shift: SDL::SCANCODE_LSHIFT, c: SDL::SCANCODE_C }.freeze
Instance Method Summary collapse
- #clear_keys ⇒ Object
-
#dump(*paths) ⇒ Object
Print just specific fields.
- #dump_state ⇒ Object
- #find_entity(classname:, targetname: nil) ⇒ Object
-
#hold(key) ⇒ Object
—- Input —-.
-
#initialize(engine, output: $stdout) ⇒ Script
constructor
A new instance of Script.
- #list_entities(classname_pattern = nil) ⇒ Object
-
#load_map(map_name) ⇒ Object
—- Map / level —-.
- #log(msg) ⇒ Object
- #noclip(enabled = true) ⇒ Object
- #press(key, frames: 2) ⇒ Object
- #release(key) ⇒ Object
- #run_block(&block) ⇒ Object
- #run_file(path) ⇒ Object
-
#screenshot(filename) ⇒ Object
—- Output —-.
- #set_pitch(pitch) ⇒ Object
- #set_yaw(yaw) ⇒ Object
-
#teleport(x, y, z, yaw: nil, pitch: nil) ⇒ Object
—- Player control —-.
-
#ticks(count, dt: DEFAULT_DT) ⇒ Object
—- Time —-.
-
#trigger(target_name) ⇒ Object
Trigger a brush entity by name (simulates a button press).
- #wait_seconds(seconds, dt: DEFAULT_DT) ⇒ Object
Constructor Details
#initialize(engine, output: $stdout) ⇒ Script
Returns a new instance of Script.
36 37 38 39 40 |
# File 'lib/quake/debug/script.rb', line 36 def initialize(engine, output: $stdout) @engine = engine @output = output @held = {} end |
Instance Method Details
#clear_keys ⇒ Object
96 97 98 99 |
# File 'lib/quake/debug/script.rb', line 96 def clear_keys @held = {} @engine.clear_keys end |
#dump(*paths) ⇒ Object
Print just specific fields
127 128 129 130 131 132 133 134 135 |
# File 'lib/quake/debug/script.rb', line 127 def dump(*paths) state = @engine.dump_state paths.each do |path| value = path.to_s.split(".").inject(state) do |acc, key| acc.is_a?(Hash) ? acc[key.to_sym] : nil end @output.puts " #{path} = #{value.inspect}" end end |
#dump_state ⇒ Object
119 120 121 122 123 124 |
# File 'lib/quake/debug/script.rb', line 119 def dump_state state = @engine.dump_state @output.puts ">> state" @output.puts JSON.pretty_generate(state) state end |
#find_entity(classname:, targetname: nil) ⇒ Object
137 138 139 140 141 |
# File 'lib/quake/debug/script.rb', line 137 def find_entity(classname:, targetname: nil) @engine.entities.find do |e| e.classname == classname && (targetname.nil? || e.targetname == targetname) end end |
#hold(key) ⇒ Object
—- Input —-
78 79 80 81 82 |
# File 'lib/quake/debug/script.rb', line 78 def hold(key) sc = scancode(key) @held[sc] = true @engine.set_key(sc, true) end |
#list_entities(classname_pattern = nil) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/quake/debug/script.rb', line 143 def list_entities(classname_pattern = nil) ents = @engine.entities if classname_pattern re = Regexp.new(classname_pattern) ents = ents.select { |e| e.classname =~ re } end ents.each do |e| @output.puts " #{e.classname} pos=#{[e.position.x, e.position.y, e.position.z].inspect} " \ "target=#{e.target.inspect} targetname=#{e.targetname.inspect}" end ents.size end |
#load_map(map_name) ⇒ Object
—- Map / level —-
52 53 54 55 |
# File 'lib/quake/debug/script.rb', line 52 def load_map(map_name) @output.puts ">> load_map #{map_name}" @engine.load_map(map_name) end |
#log(msg) ⇒ Object
162 163 164 |
# File 'lib/quake/debug/script.rb', line 162 def log(msg) @output.puts msg end |
#noclip(enabled = true) ⇒ Object
72 73 74 |
# File 'lib/quake/debug/script.rb', line 72 def noclip(enabled = true) @engine.player.noclip = enabled end |
#press(key, frames: 2) ⇒ Object
90 91 92 93 94 |
# File 'lib/quake/debug/script.rb', line 90 def press(key, frames: 2) hold(key) ticks(frames) release(key) end |
#release(key) ⇒ Object
84 85 86 87 88 |
# File 'lib/quake/debug/script.rb', line 84 def release(key) sc = scancode(key) @held[sc] = false @engine.set_key(sc, false) end |
#run_block(&block) ⇒ Object
46 47 48 |
# File 'lib/quake/debug/script.rb', line 46 def run_block(&block) instance_eval(&block) end |
#run_file(path) ⇒ Object
42 43 44 |
# File 'lib/quake/debug/script.rb', line 42 def run_file(path) instance_eval(File.read(path), path) end |
#screenshot(filename) ⇒ Object
—- Output —-
113 114 115 116 117 |
# File 'lib/quake/debug/script.rb', line 113 def screenshot(filename) FileUtils.mkdir_p(File.dirname(filename)) if filename.include?("/") @engine.screenshot(filename) @output.puts ">> screenshot #{filename}" end |
#set_pitch(pitch) ⇒ Object
68 69 70 |
# File 'lib/quake/debug/script.rb', line 68 def set_pitch(pitch) @engine.player.instance_variable_set(:@pitch, pitch.to_f) end |
#set_yaw(yaw) ⇒ Object
64 65 66 |
# File 'lib/quake/debug/script.rb', line 64 def set_yaw(yaw) @engine.player.instance_variable_set(:@yaw, yaw.to_f) end |
#teleport(x, y, z, yaw: nil, pitch: nil) ⇒ Object
—- Player control —-
59 60 61 62 |
# File 'lib/quake/debug/script.rb', line 59 def teleport(x, y, z, yaw: nil, pitch: nil) @output.puts ">> teleport (#{x}, #{y}, #{z}) yaw=#{yaw} pitch=#{pitch}" @engine.teleport(x, y, z, yaw: yaw, pitch: pitch) end |
#ticks(count, dt: DEFAULT_DT) ⇒ Object
—- Time —-
103 104 105 |
# File 'lib/quake/debug/script.rb', line 103 def ticks(count, dt: DEFAULT_DT) count.to_i.times { @engine.tick(dt) } end |
#trigger(target_name) ⇒ Object
Trigger a brush entity by name (simulates a button press)
157 158 159 160 |
# File 'lib/quake/debug/script.rb', line 157 def trigger(target_name) @engine.brush_game.send(:fire_targets, target_name) @output.puts ">> trigger #{target_name}" end |
#wait_seconds(seconds, dt: DEFAULT_DT) ⇒ Object
107 108 109 |
# File 'lib/quake/debug/script.rb', line 107 def wait_seconds(seconds, dt: DEFAULT_DT) ticks((seconds / dt).round, dt: dt) end |