gemwarrior 0.8.6 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/bin/gemwarrior +15 -9
  3. data/gemwarrior.gemspec +1 -0
  4. data/lib/gemwarrior/arena.rb +10 -10
  5. data/lib/gemwarrior/battle.rb +41 -36
  6. data/lib/gemwarrior/entities/item.rb +2 -2
  7. data/lib/gemwarrior/entities/items/arena_master.rb +4 -4
  8. data/lib/gemwarrior/entities/items/bed.rb +1 -1
  9. data/lib/gemwarrior/entities/items/couch.rb +1 -1
  10. data/lib/gemwarrior/entities/items/floor_tile.rb +3 -3
  11. data/lib/gemwarrior/entities/items/gun.rb +1 -1
  12. data/lib/gemwarrior/entities/items/herb.rb +1 -1
  13. data/lib/gemwarrior/entities/items/ladder.rb +2 -2
  14. data/lib/gemwarrior/entities/items/map.rb +2 -2
  15. data/lib/gemwarrior/entities/items/massive_door.rb +1 -1
  16. data/lib/gemwarrior/entities/items/opalaser.rb +1 -1
  17. data/lib/gemwarrior/entities/items/pond.rb +2 -2
  18. data/lib/gemwarrior/entities/items/rope.rb +2 -2
  19. data/lib/gemwarrior/entities/items/snowman.rb +1 -1
  20. data/lib/gemwarrior/entities/items/sparklything.rb +1 -1
  21. data/lib/gemwarrior/entities/items/tent.rb +1 -1
  22. data/lib/gemwarrior/entities/items/tower_switch.rb +1 -1
  23. data/lib/gemwarrior/entities/items/waterfall.rb +1 -1
  24. data/lib/gemwarrior/entities/location.rb +19 -19
  25. data/lib/gemwarrior/entities/monster.rb +2 -2
  26. data/lib/gemwarrior/entities/monsters/alexandrat.rb +3 -3
  27. data/lib/gemwarrior/entities/monsters/amberoo.rb +3 -3
  28. data/lib/gemwarrior/entities/monsters/amethystle.rb +3 -3
  29. data/lib/gemwarrior/entities/monsters/apatiger.rb +2 -2
  30. data/lib/gemwarrior/entities/monsters/aquamarine.rb +3 -3
  31. data/lib/gemwarrior/entities/monsters/bloodstorm.rb +3 -3
  32. data/lib/gemwarrior/entities/monsters/bosses/emerald.rb +4 -4
  33. data/lib/gemwarrior/entities/monsters/bosses/garynetty.rb +2 -2
  34. data/lib/gemwarrior/entities/monsters/citrinaga.rb +3 -3
  35. data/lib/gemwarrior/entities/monsters/coraliz.rb +3 -3
  36. data/lib/gemwarrior/entities/monsters/cubicat.rb +3 -3
  37. data/lib/gemwarrior/entities/monsters/diaman.rb +3 -3
  38. data/lib/gemwarrior/entities/player.rb +275 -263
  39. data/lib/gemwarrior/evaluator.rb +448 -448
  40. data/lib/gemwarrior/game.rb +5 -5
  41. data/lib/gemwarrior/inventory.rb +14 -10
  42. data/lib/gemwarrior/misc/animation.rb +1 -1
  43. data/lib/gemwarrior/misc/music.rb +1 -1
  44. data/lib/gemwarrior/misc/name_generator.rb +8 -8
  45. data/lib/gemwarrior/misc/player_levels.rb +1 -1
  46. data/lib/gemwarrior/misc/timer.rb +50 -0
  47. data/lib/gemwarrior/misc/wordlist.rb +7 -7
  48. data/lib/gemwarrior/repl.rb +55 -21
  49. data/lib/gemwarrior/version.rb +1 -1
  50. data/lib/gemwarrior/world.rb +21 -21
  51. metadata +17 -2
@@ -1,448 +1,448 @@
1
- # lib/gemwarrior/evaluator.rb
2
- # Evaluates prompt input
3
-
4
- require 'pry'
5
-
6
- require_relative 'arena'
7
-
8
- module Gemwarrior
9
- class Evaluator
10
- # CONSTANTS
11
- ## MESSAGES
12
- PROGRAM_NAME = 'Gem Warrior'
13
- QUIT_MESSAGE = 'Thanks for playing the game. Until next time...'.colorize(:yellow)
14
- RESUME_MESSAGE = 'Back to adventuring!'.colorize(:green)
15
-
16
- GO_PARAMS = 'Options: north, east, south, west'
17
- CHANGE_PARAMS = 'Options: name'
18
- DEBUG_LIST_PARAMS = 'Options: monsters, items, locations'
19
- DEBUG_STAT_PARAMS = 'Options: atk_lo, atk_hi, strength, dexterity'
20
-
21
- ## ERRORS
22
- ERROR_COMMAND_INVALID = 'That is not something the game yet understands.'
23
-
24
- ERROR_GO_PARAM_MISSING = 'Just wander aimlessly? A direction would be nice.'
25
- ERROR_GO_PARAM_INVALID = 'The place in that direction is far, far, FAR too dangerous. You should try a different way.'
26
- ERROR_ATTACK_PARAM_MISSING = 'You cannot just "attack". You gotta choose something to attack.'
27
- ERROR_ATTACK_PARAM_INVALID = 'That monster does not exist here or can\'t be attacked.'
28
- ERROR_TAKE_PARAM_MISSING = 'You cannot just "take". You gotta choose something to take.'
29
- ERROR_USE_PARAM_MISSING = 'You cannot just "use". You gotta choose something to use.'
30
- ERROR_USE_PARAM_INVALID = 'You cannot use that, as it does not exist here or in your inventory.'
31
- ERROR_USE_PARAM_UNUSEABLE = 'That object is not useable.'
32
- ERROR_DROP_PARAM_MISSING = 'You cannot just "drop". You gotta choose something to drop.'
33
- ERROR_EQUIP_PARAM_MISSING = 'You cannot just "equip". You gotta choose something to equip.'
34
- ERROR_UNEQUIP_PARAM_MISSING = 'You cannot just "unequip". You gotta choose something to unequip.'
35
- ERROR_CHANGE_PARAM_MISSING = 'You cannot just "change". You gotta choose something to change.'
36
- ERROR_CHANGE_PARAM_INVALID = 'You cannot change that...yet.'
37
- ERROR_LIST_PARAM_MISSING = 'You cannot just "list". You gotta choose something to list.'
38
- ERROR_LIST_PARAM_INVALID = 'You cannot list that...yet.'
39
- ERROR_DEBUG_STAT_PARAM_MISSING = 'You cannot just "change stats". You gotta choose a stat to change.'
40
- ERROR_DEBUG_STAT_PARAM_INVALID = 'You cannot change that stat...yet.'
41
- ERROR_DEBUG_TELEPORT_PARAMS_MISSING = 'You cannot just "teleport". You gotta specify an x AND y coordinate, at least.'
42
- ERROR_DEBUG_TELEPORT_PARAMS_NEEDED = 'You cannot just "teleport" to an x coordinate without a y coordinate.'
43
- ERROR_DEBUG_TELEPORT_PARAMS_INVALID = 'You cannot teleport there...yet.'
44
-
45
- attr_accessor :world,
46
- :commands, :aliases, :extras, :cmd_descriptions,
47
- :devcommands, :devaliases, :devextras, :devcmd_descriptions
48
-
49
- def initialize(world)
50
- self.world = world
51
-
52
- self.devcommands = %w(god beast list vars map stat teleport spawn)
53
- self.devaliases = %w(gd bs ls v m s tp sp)
54
- self.devextras = %w(st)
55
- self.devcmd_descriptions = [
56
- 'Toggle god mode (i.e. invincible)',
57
- 'Toggle beast mode (i.e. super strength)',
58
- 'List all instances of a specific entity type',
59
- 'List all the variables in the world',
60
- 'Show a map of the world',
61
- 'Change player stat',
62
- 'Teleport to coordinates (5 0 0) or location name (\'Home\')',
63
- 'Spawn random monster'
64
- ]
65
-
66
- self.commands = %w(character inventory rest look take use drop equip unequip go attack change help quit quit!)
67
- self.aliases = %w(c i r l t u d e ue g a ch h q qq)
68
- self.extras = %w(exit exit! x x fight f)
69
- self.cmd_descriptions = [
70
- 'Display character information',
71
- 'Look in your inventory',
72
- 'Take a load off and regain HP',
73
- 'Look around your current location',
74
- 'Take item',
75
- 'Use item (in inventory or environment)',
76
- 'Drop item',
77
- 'Equip item',
78
- 'Unequip item',
79
- 'Go in a direction',
80
- 'Attack a monster',
81
- 'Change something',
82
- 'This help menu',
83
- 'Quit w/ confirmation (also exit/x)',
84
- 'Quit w/o confirmation (also exit!/xx)'
85
- ]
86
- end
87
-
88
- def evaluate(input)
89
- case input
90
- # Ctrl-D or empty command
91
- when nil, ""
92
- return
93
- # real command
94
- else
95
- tokens = input.split
96
- unless input_valid?(input)
97
- return ERROR_COMMAND_INVALID
98
- end
99
- end
100
-
101
- command = tokens.first.downcase
102
- param1 = tokens[1]
103
- param2 = tokens[2]
104
- param3 = tokens[3]
105
-
106
- # dev commands
107
- if world.debug_mode
108
- case command
109
- when 'god', 'gd'
110
- return world.player.god_mode = !world.player.god_mode
111
- when 'beast', 'bs'
112
- return world.player.beast_mode = !world.player.beast_mode
113
- when 'vars', 'v'
114
- world.print_vars
115
- when 'list', 'ls'
116
- if param1.nil?
117
- puts ERROR_LIST_PARAM_MISSING
118
- return DEBUG_LIST_PARAMS
119
- else
120
- return world.list(param1, param2)
121
- end
122
- when 'map', 'm'
123
- world.print_map
124
- when 'stat', 'st', 's'
125
- if param1.nil?
126
- puts ERROR_DEBUG_STAT_PARAM_MISSING
127
- return DEBUG_STAT_PARAMS
128
- else
129
- case param1
130
- when 'hp_cur'
131
- unless param2.nil?
132
- param2 = param2.to_i
133
- if param2.is_a? Numeric
134
- if param2 > 0
135
- world.player.hp_cur = param2
136
- end
137
- end
138
- end
139
- when 'atk_lo'
140
- unless param2.nil?
141
- param2 = param2.to_i
142
- if param2.is_a? Numeric
143
- if param2 >= 0
144
- world.player.atk_lo = param2
145
- end
146
- end
147
- end
148
- when 'atk_hi'
149
- unless param2.nil?
150
- param2 = param2.to_i
151
- if param2.is_a? Numeric
152
- if param2 >= 0
153
- world.player.atk_hi = param2
154
- end
155
- end
156
- end
157
- when 'strength', 'str', 'st'
158
- unless param2.nil?
159
- param2 = param2.to_i
160
- if param2.is_a? Numeric
161
- if param2 >= 0
162
- world.player.atk_lo = param2
163
- world.player.atk_hi = param2
164
- end
165
- end
166
- end
167
- when 'dexterity', 'dex', 'd'
168
- unless param2.nil?
169
- param2 = param2.to_i
170
- if param2.is_a? Numeric
171
- if param2 >= 0
172
- world.player.dexterity = param2
173
- end
174
- end
175
- end
176
- when 'rox', 'r', '$'
177
- unless param2.nil?
178
- param2 = param2.to_i
179
- if param2.is_a? Numeric
180
- if param2 >= 0
181
- world.player.rox = param2
182
- end
183
- end
184
- end
185
- else
186
- return ERROR_DEBUG_STAT_PARAM_INVALID
187
- end
188
- end
189
- when 'spawn', 'sp'
190
- cur_loc = world.location_by_coords(world.player.cur_coords)
191
- cur_loc.populate_monsters(world.monsters, true)
192
- return world.describe(cur_loc)
193
- when 'teleport', 'tp'
194
- if param1.nil?
195
- return ERROR_DEBUG_TELEPORT_PARAMS_MISSING
196
- else
197
- if (param1.to_i.to_s == param1)
198
- # we got at least an x coordinate
199
- if (param2.to_i.to_s == param2)
200
- # we got a y coordinate, too
201
- x_coord = param1.to_i
202
- y_coord = param2.to_i
203
- # grab the z coordinate, if present, otherwise default to current level
204
- z_coord = param3.to_i.to_s == param3 ? param3.to_i : world.player.cur_coords[:z]
205
-
206
- # check to make sure new location exists
207
- if world.location_by_coords({:x => x_coord, :y => y_coord, :z => z_coord})
208
- world.player.cur_coords = {:x => x_coord, :y => y_coord, :z => z_coord}
209
- else
210
- return ERROR_DEBUG_TELEPORT_PARAMS_INVALID
211
- end
212
- else
213
- # we only got an x coordinate
214
- return ERROR_DEBUG_TELEPORT_PARAMS_NEEDED
215
- end
216
- else
217
- # we got a place name instead, potentially
218
- place_to_match = tokens[1..tokens.length].join(' ').downcase
219
- locations = []
220
- world.locations.each do |l|
221
- locations << l.name.downcase
222
- end
223
- if locations.include?(place_to_match)
224
- world.player.cur_coords = world.location_coords_by_name(place_to_match)
225
- else
226
- return ERROR_DEBUG_TELEPORT_PARAMS_INVALID
227
- end
228
- end
229
- Animation::run({:phrase => '** TELEPORT! **', :speed => :insane})
230
- return world.describe(world.location_by_coords(world.player.cur_coords))
231
- end
232
- end
233
- end
234
-
235
- # normal commands
236
- case command
237
- when 'character', 'c'
238
- world.player.check_self(world.debug_mode)
239
- when 'inventory', 'i'
240
- if param1
241
- world.player.inventory.describe_item(param1)
242
- else
243
- world.player.list_inventory
244
- end
245
- when 'rest', 'r'
246
- world.player.rest(world)
247
- when 'look', 'l'
248
- if param1
249
- world.describe_entity(world.location_by_coords(world.player.cur_coords), param1)
250
- else
251
- world.describe(world.location_by_coords(world.player.cur_coords))
252
- end
253
- when 'take', 't'
254
- if param1.nil?
255
- ERROR_TAKE_PARAM_MISSING
256
- else
257
- world.player.inventory.add_item(world.location_by_coords(world.player.cur_coords), param1)
258
- end
259
- when 'use', 'u'
260
- if param1.nil?
261
- ERROR_USE_PARAM_MISSING
262
- else
263
- item_name = param1
264
- result = nil
265
- location_inventory = world.location_by_coords(world.player.cur_coords).items
266
-
267
- if location_inventory.map(&:name).include?(item_name)
268
- location_inventory.each do |i|
269
- if i.name.eql?(item_name)
270
- if i.useable
271
- result = i.use(world.player)
272
- else
273
- return ERROR_USE_PARAM_UNUSEABLE
274
- end
275
- end
276
- end
277
- elsif
278
- player_inventory = world.player.inventory.items
279
- if player_inventory.map(&:name).include?(item_name)
280
- player_inventory.each do |i|
281
- if i.name.eql?(item_name)
282
- if i.useable
283
- result = i.use(world.player)
284
- else
285
- return ERROR_USE_PARAM_UNUSEABLE
286
- end
287
- end
288
- end
289
- end
290
- end
291
-
292
- if result.nil?
293
- ERROR_USE_PARAM_INVALID
294
- else
295
- case result[:type]
296
- when 'move'
297
- world.player.cur_coords = world.location_coords_by_name(result[:data])
298
- world.describe(world.location_by_coords(world.player.cur_coords))
299
- when 'move_dangerous'
300
- world.player.take_damage(rand(0..2))
301
- world.player.cur_coords = world.location_coords_by_name(result[:data])
302
- world.describe(world.location_by_coords(world.player.cur_coords))
303
- when 'dmg'
304
- world.player.take_damage(result[:data])
305
- return
306
- when 'rest', 'health'
307
- world.player.heal_damage(result[:data])
308
- return
309
- when 'action'
310
- case result[:data]
311
- when 'rest'
312
- world.player.rest(world)
313
- when 'map'
314
- world.print_map
315
- end
316
- when 'arena'
317
- arena = Arena.new({:world => world, :player => world.player})
318
- arena.start
319
- #return 'You enter the arena and fight some battles. It was cool, but not as cool as if it were actually implemented.'
320
- when 'item'
321
- world.location_by_coords(world.player.cur_coords).add_item(result[:data])
322
- return
323
- else
324
- return
325
- end
326
- end
327
- end
328
- when 'drop', 'd'
329
- if param1.nil?
330
- ERROR_DROP_PARAM_MISSING
331
- else
332
- world.player.inventory.remove_item(param1)
333
- end
334
- when 'equip', 'e'
335
- if param1.nil?
336
- ERROR_EQUIP_PARAM_MISSING
337
- else
338
- world.player.inventory.equip_item(param1)
339
- end
340
- when 'unequip', 'ue'
341
- if param1.nil?
342
- ERROR_UNEQUIP_PARAM_MISSING
343
- else
344
- world.player.inventory.unequip_item(param1)
345
- end
346
- when 'go', 'g'
347
- if param1.nil?
348
- puts ERROR_GO_PARAM_MISSING
349
- GO_PARAMS
350
- else
351
- direction = param1
352
- if world.can_move?(direction)
353
- world.player.go(world.locations, param1, world.sound)
354
- world.location_by_coords(world.player.cur_coords).checked_for_monsters = false
355
- world.describe(world.location_by_coords(world.player.cur_coords))
356
- else
357
- ERROR_GO_PARAM_INVALID
358
- end
359
- end
360
- when 'attack', 'a', 'fight', 'f'
361
- if param1.nil?
362
- ERROR_ATTACK_PARAM_MISSING
363
- else
364
- monster_name = param1
365
- if world.has_monster_to_attack?(monster_name)
366
- monster = world.location_by_coords(world.player.cur_coords).monster_by_name(monster_name)
367
- world.player.attack(world, monster)
368
- else
369
- ERROR_ATTACK_PARAM_INVALID
370
- end
371
- end
372
- when 'change', 'ch'
373
- if param1.nil?
374
- puts ERROR_CHANGE_PARAM_MISSING
375
- CHANGE_PARAMS
376
- else
377
- case param1
378
- when 'name'
379
- world.player.modify_name
380
- else
381
- ERROR_CHANGE_PARAM_INVALID
382
- end
383
- end
384
- when 'help', 'h'
385
- list_commands
386
- when 'quit', 'exit', 'q', 'x'
387
- puts "You sure you want to quit? (y/n): "
388
- response = gets.chomp.downcase
389
- if (response.eql?("y") || response.eql?("yes"))
390
- puts QUIT_MESSAGE
391
- exit(0)
392
- else
393
- puts RESUME_MESSAGE
394
- end
395
- when 'quit!', 'exit!', 'qq', 'xx'
396
- puts QUIT_MESSAGE
397
- exit(0)
398
- else
399
- return
400
- end
401
- end
402
-
403
- private
404
-
405
- def print_separator
406
- puts "=================================================="
407
- end
408
-
409
- def list_commands
410
- i = 0
411
- print_separator
412
- commands.each do |cmd|
413
- puts " #{cmd.ljust(9)}, #{aliases[i].ljust(2)} -- #{cmd_descriptions[i]}"
414
- i = i + 1
415
- end
416
- print_separator
417
-
418
- if world.debug_mode
419
- puts " DEBUG COMMANDS"
420
- print_separator
421
- i = 0
422
- devcommands.each do |cmd|
423
- puts " #{cmd.ljust(9)}, #{devaliases[i].ljust(2)} -- #{devcmd_descriptions[i]}"
424
- i = i + 1
425
- end
426
- print_separator
427
- end
428
- end
429
-
430
- def input_valid?(input)
431
- tokens = input.split
432
- command = tokens[0]
433
- commands_and_aliases = commands | aliases | extras
434
-
435
- if world.debug_mode
436
- commands_and_aliases = commands_and_aliases | devcommands | devaliases | devextras
437
- end
438
-
439
- if commands_and_aliases.include?(command.downcase)
440
- if tokens.size.between?(1,4)
441
- return true
442
- end
443
- elsif tokens.empty?
444
- return true
445
- end
446
- end
447
- end
448
- end
1
+ # lib/gemwarrior/evaluator.rb
2
+ # Evaluates prompt input
3
+
4
+ require 'pry'
5
+
6
+ require_relative 'arena'
7
+
8
+ module Gemwarrior
9
+ class Evaluator
10
+ # CONSTANTS
11
+ ## MESSAGES
12
+ PROGRAM_NAME = 'Gem Warrior'
13
+ QUIT_MESSAGE = 'Thanks for playing the game. Until next time...'.colorize(:yellow)
14
+ RESUME_MESSAGE = 'Back to adventuring!'.colorize(:green)
15
+
16
+ GO_PARAMS = 'Options: north, east, south, west'
17
+ CHANGE_PARAMS = 'Options: name'
18
+ DEBUG_LIST_PARAMS = 'Options: monsters, items, locations'
19
+ DEBUG_STAT_PARAMS = 'Options: atk_lo, atk_hi, strength, dexterity'
20
+
21
+ ## ERRORS
22
+ ERROR_COMMAND_INVALID = 'That is not something the game yet understands.'
23
+
24
+ ERROR_GO_PARAM_MISSING = 'Just wander aimlessly? A direction would be nice.'
25
+ ERROR_GO_PARAM_INVALID = 'The place in that direction is far, far, FAR too dangerous. You should try a different way.'
26
+ ERROR_ATTACK_PARAM_MISSING = 'You cannot just "attack". You gotta choose something to attack.'
27
+ ERROR_ATTACK_PARAM_INVALID = 'That monster does not exist here or can\'t be attacked.'
28
+ ERROR_TAKE_PARAM_MISSING = 'You cannot just "take". You gotta choose something to take.'
29
+ ERROR_USE_PARAM_MISSING = 'You cannot just "use". You gotta choose something to use.'
30
+ ERROR_USE_PARAM_INVALID = 'You cannot use that, as it does not exist here or in your inventory.'
31
+ ERROR_USE_PARAM_UNUSEABLE = 'That object is not useable.'
32
+ ERROR_DROP_PARAM_MISSING = 'You cannot just "drop". You gotta choose something to drop.'
33
+ ERROR_EQUIP_PARAM_MISSING = 'You cannot just "equip". You gotta choose something to equip.'
34
+ ERROR_UNEQUIP_PARAM_MISSING = 'You cannot just "unequip". You gotta choose something to unequip.'
35
+ ERROR_CHANGE_PARAM_MISSING = 'You cannot just "change". You gotta choose something to change.'
36
+ ERROR_CHANGE_PARAM_INVALID = 'You cannot change that...yet.'
37
+ ERROR_LIST_PARAM_MISSING = 'You cannot just "list". You gotta choose something to list.'
38
+ ERROR_LIST_PARAM_INVALID = 'You cannot list that...yet.'
39
+ ERROR_DEBUG_STAT_PARAM_MISSING = 'You cannot just "change stats". You gotta choose a stat to change.'
40
+ ERROR_DEBUG_STAT_PARAM_INVALID = 'You cannot change that stat...yet.'
41
+ ERROR_DEBUG_TELEPORT_PARAMS_MISSING = 'You cannot just "teleport". You gotta specify an x AND y coordinate, at least.'
42
+ ERROR_DEBUG_TELEPORT_PARAMS_NEEDED = 'You cannot just "teleport" to an x coordinate without a y coordinate.'
43
+ ERROR_DEBUG_TELEPORT_PARAMS_INVALID = 'You cannot teleport there...yet.'
44
+
45
+ attr_accessor :world,
46
+ :commands, :aliases, :extras, :cmd_descriptions,
47
+ :devcommands, :devaliases, :devextras, :devcmd_descriptions
48
+
49
+ def initialize(world)
50
+ self.world = world
51
+
52
+ self.devcommands = %w(god beast list vars map stat teleport spawn)
53
+ self.devaliases = %w(gd bs ls v m s tp sp)
54
+ self.devextras = %w(st)
55
+ self.devcmd_descriptions = [
56
+ 'Toggle god mode (i.e. invincible)',
57
+ 'Toggle beast mode (i.e. super strength)',
58
+ 'List all instances of a specific entity type',
59
+ 'List all the variables in the world',
60
+ 'Show a map of the world',
61
+ 'Change player stat',
62
+ 'Teleport to coordinates (5 0 0) or location name (\'Home\')',
63
+ 'Spawn random monster'
64
+ ]
65
+
66
+ self.commands = %w(character inventory rest look take use drop equip unequip go attack change help quit quit!)
67
+ self.aliases = %w(c i r l t u d e ue g a ch h q qq)
68
+ self.extras = %w(exit exit! x x fight f)
69
+ self.cmd_descriptions = [
70
+ 'Display character information',
71
+ 'Look in your inventory',
72
+ 'Take a load off and regain HP',
73
+ 'Look around your current location',
74
+ 'Take item',
75
+ 'Use item (in inventory or environment)',
76
+ 'Drop item',
77
+ 'Equip item',
78
+ 'Unequip item',
79
+ 'Go in a direction',
80
+ 'Attack a monster',
81
+ 'Change something',
82
+ 'This help menu',
83
+ 'Quit w/ confirmation (also exit/x)',
84
+ 'Quit w/o confirmation (also exit!/xx)'
85
+ ]
86
+ end
87
+
88
+ def evaluate(input)
89
+ case input
90
+ # Ctrl-D or empty command
91
+ when nil, ""
92
+ return
93
+ # real command
94
+ else
95
+ tokens = input.split
96
+ unless input_valid?(input)
97
+ return ERROR_COMMAND_INVALID
98
+ end
99
+ end
100
+
101
+ command = tokens.first.downcase
102
+ param1 = tokens[1]
103
+ param2 = tokens[2]
104
+ param3 = tokens[3]
105
+
106
+ # dev commands
107
+ if world.debug_mode
108
+ case command
109
+ when 'god', 'gd'
110
+ return world.player.god_mode = !world.player.god_mode
111
+ when 'beast', 'bs'
112
+ return world.player.beast_mode = !world.player.beast_mode
113
+ when 'vars', 'v'
114
+ world.print_vars
115
+ when 'list', 'ls'
116
+ if param1.nil?
117
+ puts ERROR_LIST_PARAM_MISSING
118
+ return DEBUG_LIST_PARAMS
119
+ else
120
+ return world.list(param1, param2)
121
+ end
122
+ when 'map', 'm'
123
+ world.print_map
124
+ when 'stat', 'st', 's'
125
+ if param1.nil?
126
+ puts ERROR_DEBUG_STAT_PARAM_MISSING
127
+ return DEBUG_STAT_PARAMS
128
+ else
129
+ case param1
130
+ when 'hp_cur'
131
+ unless param2.nil?
132
+ param2 = param2.to_i
133
+ if param2.is_a? Numeric
134
+ if param2 > 0
135
+ world.player.hp_cur = param2
136
+ end
137
+ end
138
+ end
139
+ when 'atk_lo'
140
+ unless param2.nil?
141
+ param2 = param2.to_i
142
+ if param2.is_a? Numeric
143
+ if param2 >= 0
144
+ world.player.atk_lo = param2
145
+ end
146
+ end
147
+ end
148
+ when 'atk_hi'
149
+ unless param2.nil?
150
+ param2 = param2.to_i
151
+ if param2.is_a? Numeric
152
+ if param2 >= 0
153
+ world.player.atk_hi = param2
154
+ end
155
+ end
156
+ end
157
+ when 'strength', 'str', 'st'
158
+ unless param2.nil?
159
+ param2 = param2.to_i
160
+ if param2.is_a? Numeric
161
+ if param2 >= 0
162
+ world.player.atk_lo = param2
163
+ world.player.atk_hi = param2
164
+ end
165
+ end
166
+ end
167
+ when 'dexterity', 'dex', 'd'
168
+ unless param2.nil?
169
+ param2 = param2.to_i
170
+ if param2.is_a? Numeric
171
+ if param2 >= 0
172
+ world.player.dexterity = param2
173
+ end
174
+ end
175
+ end
176
+ when 'rox', 'r', '$'
177
+ unless param2.nil?
178
+ param2 = param2.to_i
179
+ if param2.is_a? Numeric
180
+ if param2 >= 0
181
+ world.player.rox = param2
182
+ end
183
+ end
184
+ end
185
+ else
186
+ return ERROR_DEBUG_STAT_PARAM_INVALID
187
+ end
188
+ end
189
+ when 'spawn', 'sp'
190
+ cur_loc = world.location_by_coords(world.player.cur_coords)
191
+ cur_loc.populate_monsters(world.monsters, true)
192
+ return world.describe(cur_loc)
193
+ when 'teleport', 'tp'
194
+ if param1.nil?
195
+ return ERROR_DEBUG_TELEPORT_PARAMS_MISSING
196
+ else
197
+ if (param1.to_i.to_s == param1)
198
+ # we got at least an x coordinate
199
+ if (param2.to_i.to_s == param2)
200
+ # we got a y coordinate, too
201
+ x_coord = param1.to_i
202
+ y_coord = param2.to_i
203
+ # grab the z coordinate, if present, otherwise default to current level
204
+ z_coord = param3.to_i.to_s == param3 ? param3.to_i : world.player.cur_coords[:z]
205
+
206
+ # check to make sure new location exists
207
+ if world.location_by_coords({:x => x_coord, :y => y_coord, :z => z_coord})
208
+ world.player.cur_coords = {:x => x_coord, :y => y_coord, :z => z_coord}
209
+ else
210
+ return ERROR_DEBUG_TELEPORT_PARAMS_INVALID
211
+ end
212
+ else
213
+ # we only got an x coordinate
214
+ return ERROR_DEBUG_TELEPORT_PARAMS_NEEDED
215
+ end
216
+ else
217
+ # we got a place name instead, potentially
218
+ place_to_match = tokens[1..tokens.length].join(' ').downcase
219
+ locations = []
220
+ world.locations.each do |l|
221
+ locations << l.name.downcase
222
+ end
223
+ if locations.include?(place_to_match)
224
+ world.player.cur_coords = world.location_coords_by_name(place_to_match)
225
+ else
226
+ return ERROR_DEBUG_TELEPORT_PARAMS_INVALID
227
+ end
228
+ end
229
+ Animation::run({:phrase => '** TELEPORT! **', :speed => :insane})
230
+ return world.describe(world.location_by_coords(world.player.cur_coords))
231
+ end
232
+ end
233
+ end
234
+
235
+ # normal commands
236
+ case command
237
+ when 'character', 'c'
238
+ world.player.check_self(world.debug_mode)
239
+ when 'inventory', 'i'
240
+ if param1
241
+ world.player.inventory.describe_item(param1)
242
+ else
243
+ world.player.list_inventory
244
+ end
245
+ when 'rest', 'r'
246
+ world.player.rest(world)
247
+ when 'look', 'l'
248
+ if param1
249
+ world.describe_entity(world.location_by_coords(world.player.cur_coords), param1)
250
+ else
251
+ world.describe(world.location_by_coords(world.player.cur_coords))
252
+ end
253
+ when 'take', 't'
254
+ if param1.nil?
255
+ ERROR_TAKE_PARAM_MISSING
256
+ else
257
+ world.player.inventory.add_item(world.location_by_coords(world.player.cur_coords), param1, world.player)
258
+ end
259
+ when 'use', 'u'
260
+ if param1.nil?
261
+ ERROR_USE_PARAM_MISSING
262
+ else
263
+ item_name = param1
264
+ result = nil
265
+ location_inventory = world.location_by_coords(world.player.cur_coords).items
266
+
267
+ if location_inventory.map(&:name).include?(item_name)
268
+ location_inventory.each do |i|
269
+ if i.name.eql?(item_name)
270
+ if i.useable
271
+ result = i.use(world.player)
272
+ else
273
+ return ERROR_USE_PARAM_UNUSEABLE
274
+ end
275
+ end
276
+ end
277
+ elsif
278
+ player_inventory = world.player.inventory.items
279
+ if player_inventory.map(&:name).include?(item_name)
280
+ player_inventory.each do |i|
281
+ if i.name.eql?(item_name)
282
+ if i.useable
283
+ result = i.use(world.player)
284
+ else
285
+ return ERROR_USE_PARAM_UNUSEABLE
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end
291
+
292
+ if result.nil?
293
+ ERROR_USE_PARAM_INVALID
294
+ else
295
+ case result[:type]
296
+ when 'move'
297
+ world.player.cur_coords = world.location_coords_by_name(result[:data])
298
+ world.describe(world.location_by_coords(world.player.cur_coords))
299
+ when 'move_dangerous'
300
+ world.player.take_damage(rand(0..2))
301
+ world.player.cur_coords = world.location_coords_by_name(result[:data])
302
+ world.describe(world.location_by_coords(world.player.cur_coords))
303
+ when 'dmg'
304
+ world.player.take_damage(result[:data])
305
+ return
306
+ when 'rest', 'health'
307
+ world.player.heal_damage(result[:data])
308
+ return
309
+ when 'action'
310
+ case result[:data]
311
+ when 'rest'
312
+ world.player.rest(world)
313
+ when 'map'
314
+ world.print_map
315
+ end
316
+ when 'arena'
317
+ arena = Arena.new({:world => world, :player => world.player})
318
+ arena.start
319
+ #return 'You enter the arena and fight some battles. It was cool, but not as cool as if it were actually implemented.'
320
+ when 'item'
321
+ world.location_by_coords(world.player.cur_coords).add_item(result[:data])
322
+ return
323
+ else
324
+ return
325
+ end
326
+ end
327
+ end
328
+ when 'drop', 'd'
329
+ if param1.nil?
330
+ ERROR_DROP_PARAM_MISSING
331
+ else
332
+ world.player.inventory.remove_item(param1)
333
+ end
334
+ when 'equip', 'e'
335
+ if param1.nil?
336
+ ERROR_EQUIP_PARAM_MISSING
337
+ else
338
+ world.player.inventory.equip_item(param1)
339
+ end
340
+ when 'unequip', 'ue'
341
+ if param1.nil?
342
+ ERROR_UNEQUIP_PARAM_MISSING
343
+ else
344
+ world.player.inventory.unequip_item(param1)
345
+ end
346
+ when 'go', 'g'
347
+ if param1.nil?
348
+ puts ERROR_GO_PARAM_MISSING
349
+ GO_PARAMS
350
+ else
351
+ direction = param1
352
+ if world.can_move?(direction)
353
+ world.player.go(world.locations, param1, world.sound)
354
+ world.location_by_coords(world.player.cur_coords).checked_for_monsters = false
355
+ world.describe(world.location_by_coords(world.player.cur_coords))
356
+ else
357
+ ERROR_GO_PARAM_INVALID
358
+ end
359
+ end
360
+ when 'attack', 'a', 'fight', 'f'
361
+ if param1.nil?
362
+ ERROR_ATTACK_PARAM_MISSING
363
+ else
364
+ monster_name = param1
365
+ if world.has_monster_to_attack?(monster_name)
366
+ monster = world.location_by_coords(world.player.cur_coords).monster_by_name(monster_name)
367
+ world.player.attack(world, monster)
368
+ else
369
+ ERROR_ATTACK_PARAM_INVALID
370
+ end
371
+ end
372
+ when 'change', 'ch'
373
+ if param1.nil?
374
+ puts ERROR_CHANGE_PARAM_MISSING
375
+ CHANGE_PARAMS
376
+ else
377
+ case param1
378
+ when 'name'
379
+ world.player.modify_name
380
+ else
381
+ ERROR_CHANGE_PARAM_INVALID
382
+ end
383
+ end
384
+ when 'help', 'h'
385
+ list_commands
386
+ when 'quit', 'exit', 'q', 'x'
387
+ puts "You sure you want to quit? (y/n): "
388
+ response = gets.chomp.downcase
389
+ if (response.eql?("y") || response.eql?("yes"))
390
+ puts QUIT_MESSAGE
391
+ return 'exit'
392
+ else
393
+ puts RESUME_MESSAGE
394
+ end
395
+ when 'quit!', 'exit!', 'qq', 'xx'
396
+ puts QUIT_MESSAGE
397
+ return 'exit'
398
+ else
399
+ return
400
+ end
401
+ end
402
+
403
+ private
404
+
405
+ def print_separator
406
+ puts "=================================================="
407
+ end
408
+
409
+ def list_commands
410
+ i = 0
411
+ print_separator
412
+ commands.each do |cmd|
413
+ puts " #{cmd.ljust(9)}, #{aliases[i].ljust(2)} -- #{cmd_descriptions[i]}"
414
+ i = i + 1
415
+ end
416
+ print_separator
417
+
418
+ if world.debug_mode
419
+ puts " DEBUG COMMANDS"
420
+ print_separator
421
+ i = 0
422
+ devcommands.each do |cmd|
423
+ puts " #{cmd.ljust(9)}, #{devaliases[i].ljust(2)} -- #{devcmd_descriptions[i]}"
424
+ i = i + 1
425
+ end
426
+ print_separator
427
+ end
428
+ end
429
+
430
+ def input_valid?(input)
431
+ tokens = input.split
432
+ command = tokens[0]
433
+ commands_and_aliases = commands | aliases | extras
434
+
435
+ if world.debug_mode
436
+ commands_and_aliases = commands_and_aliases | devcommands | devaliases | devextras
437
+ end
438
+
439
+ if commands_and_aliases.include?(command.downcase)
440
+ if tokens.size.between?(1,4)
441
+ return true
442
+ end
443
+ elsif tokens.empty?
444
+ return true
445
+ end
446
+ end
447
+ end
448
+ end