gemwarrior 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5f01219fe323d1a74d0205758b61084bbea01e4e
4
- data.tar.gz: 1dc551158da4ddcb6737c7daa15c33e151eaf5a3
3
+ metadata.gz: 638aef0b767f40757bdadab429977bdcd2f23c22
4
+ data.tar.gz: 9e7a30b926f56dee75605ac92a41a966c6886e7c
5
5
  SHA512:
6
- metadata.gz: 0099d78162db97ca70e0fc6760f103ee720667262a763c5a294d1c1fb505b2ac26827601673304c7eadb72674a1e2b28a0e5f0f0a1b4fdf77ca87aa22e962922
7
- data.tar.gz: a9a84abd388aca04244c7afd9d558ac27ba460b4d2ba62505e12f1df3936791108e15d7f67aef06aaf9ebd1f6ec3dfa33a4a11bb870b4f4e5a1499e3ad74632c
6
+ metadata.gz: a231f1497002ec5a325e913b156595b067a5ccfabd77f966c6e4861d73a07a6197e1dc8ddc096d912c309df82b2bbf34189a80ebe51c99799e567b437580b93e
7
+ data.tar.gz: ddd8a4352f8e0691a67c6e382221b4a8cbb05c9c3de312f7ab7545e8e82a126e5812fba2fcf81bb4abfe6108a29343d2a0e9df06ee3a50501db8d516af4bfd64
data/README.md CHANGED
@@ -17,10 +17,12 @@ As you travel you will discover sights and sounds of the land, all of which are
17
17
 
18
18
  ## How to Get to Jool
19
19
 
20
- 1. `gem install gemwarrior`
21
- 2. `gemwarrior`
20
+ 1. `ruby -v` should return `ruby 2.`something; else install [Ruby](https://www.ruby-lang.org)
21
+ 2. `gem -v` should return `2.`something; else install [RubyGems](https://rubygems.org)
22
+ 2. `gem install gemwarrior`
23
+ 3. `gemwarrior`
22
24
 
23
- Run the two commands above and you'll be whisked away to Jool, ready to start or continue your quest to defeat Emerald and take back the coveted Shiny Thing(tm) that you will bring back to Queen Ruby (or will you...?).
25
+ Run the commands above and you'll be whisked away to Jool, ready to start or continue your quest to defeat Emerald and take back the coveted Shiny Thing(tm) that you will bring back to Queen Ruby (or will you...?).
24
26
 
25
27
  ## In Progress, Yanno
26
28
 
@@ -30,6 +32,7 @@ This is in super-hyper-turbo-edition pre-pre-pre-alpha right now, but a working
30
32
  `> i [object]` - check your inventory (or an individual item within)
31
33
  `> r` - take a load off (future: replenish stamina)
32
34
  `> l [object]` - look at current location and its items and monsters
35
+ `> ls [entity_type]` - list entities in the game (monsters, items, locations)
33
36
  `> t [object]` - take an item from a location
34
37
  `> e [object]` - equip an item in your inventory as a weapon
35
38
  `> a [monster]` - attack a monster
@@ -42,13 +45,15 @@ This is in super-hyper-turbo-edition pre-pre-pre-alpha right now, but a working
42
45
  To come:
43
46
 
44
47
  * ~~Ability to move between locations!~~
45
- * More locations to move between!
46
48
  * ~~Monsters!~~
47
49
  * ~~Ability to fight those monsters!~~
48
50
  * Monsters to fight back!
49
51
  * ~~Items you can pick up!~~
50
- * Quests!
51
- * Towns!
52
+ * Saving!
53
+ * Loading of said saved state!
54
+ * More locations to move between!
55
+ * Quests (maybe)!
56
+ * Towns (maybe)!
52
57
  * Merchants!
53
58
  * Sound FX!
54
59
  * Music!
data/bin/gemwarrior CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'optparse'
4
4
 
5
- require_relative '../lib/gemwarrior/version'
5
+ require_relative '../lib/gemwarrior/misc/version'
6
6
  require_relative '../lib/gemwarrior/game'
7
7
 
8
8
  def parse_options
data/gemwarrior.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'gemwarrior/version'
4
+ require 'gemwarrior/misc/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'gemwarrior'
@@ -0,0 +1,27 @@
1
+ # lib/gemwarrior/entities/creature.rb
2
+ # Creature base class
3
+
4
+ require_relative 'entity'
5
+ require_relative '../inventory'
6
+
7
+ module Gemwarrior
8
+ class Creature < Entity
9
+ attr_accessor :id, :name, :description, :face, :hands, :mood,
10
+ :level, :hp_cur, :hp_max, :inventory
11
+
12
+ def initialize(options)
13
+ self.id = options[:id]
14
+ self.name = options[:name]
15
+ self.description = options[:description]
16
+ self.face = options[:face]
17
+ self.hands = options[:hands]
18
+ self.mood = options[:mood]
19
+
20
+ self.level = options[:level]
21
+ self.hp_cur = options[:hp_cur]
22
+ self.hp_max = options[:hp_max]
23
+
24
+ self.inventory = options[:inventory]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ # lib/gemwarrior/entities/entity.rb
2
+ # Base class for an interactable object
3
+
4
+ module Gemwarrior
5
+ class Entity
6
+ attr_reader :id, :name, :description
7
+
8
+ def initialize(options)
9
+ self.id = options[:id]
10
+ self.name = options[:name]
11
+ self.description = options[:description]
12
+ end
13
+
14
+ def status
15
+ status_text = name.ljust(20).upcase
16
+ status_text << "#{description}\n"
17
+ status_text.to_s
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # lib/gemwarrior/entities/item.rb
2
+ # Item base class
3
+
4
+ require_relative 'entity'
5
+
6
+ module Gemwarrior
7
+ class Item < Entity
8
+ attr_accessor :id, :name, :description,
9
+ :atk_lo, :atk_hi, :takeable, :equippable, :equipped
10
+
11
+ def initialize(options)
12
+ self.id = options[:id]
13
+ self.name = options[:name]
14
+ self.description = options[:description]
15
+ self.atk_lo = options[:atk_lo]
16
+ self.atk_hi = options[:atk_hi]
17
+ self.takeable = options[:takeable]
18
+ self.equippable = options[:equippable]
19
+ self.equipped = options[:equipped]
20
+ end
21
+ end
22
+ end
@@ -1,10 +1,12 @@
1
- # lib/gemwarrior/location.rb
1
+ # lib/gemwarrior/entities/location.rb
2
2
  # Place in the game
3
3
 
4
4
  require 'matrext'
5
5
 
6
+ require_relative 'entity'
7
+
6
8
  module Gemwarrior
7
- class Location
9
+ class Location < Entity
8
10
  # CONSTANTS
9
11
  ## HASHES
10
12
  DANGER_LEVEL = {:none => 0, :low => 15, :moderate => 30, :high => 55, :assured => 100}
@@ -16,15 +18,15 @@ module Gemwarrior
16
18
  attr_accessor :id, :name, :description, :locs_connected, :danger_level,
17
19
  :items, :monsters_available, :monsters_abounding, :checked_for_monsters
18
20
 
19
- def initialize(id, name, description, locs_connected, danger_level, items, monsters_available)
20
- self.id = id
21
- self.name = name
22
- self.description = description
23
- self.locs_connected = locs_connected
24
- self.danger_level = danger_level
25
- self.items = items
26
- self.monsters_available = monsters_available
27
- self.monsters_abounding = []
21
+ def initialize(options)
22
+ self.id = options[:id]
23
+ self.name = options[:name]
24
+ self.description = options[:description]
25
+ self.locs_connected = options[:locs_connected]
26
+ self.danger_level = options[:danger_level]
27
+ self.items = options[:items]
28
+ self.monsters_available = options[:monsters_available]
29
+ self.monsters_abounding = []
28
30
  self.checked_for_monsters = false
29
31
  end
30
32
 
@@ -91,7 +93,7 @@ module Gemwarrior
91
93
  def monster_by_name(name)
92
94
  monsters_abounding.each do |m|
93
95
  if m.name.eql?(name)
94
- return m
96
+ return m.clone
95
97
  end
96
98
  end
97
99
  end
@@ -0,0 +1,53 @@
1
+ # lib/gemwarrior/entities/monster.rb
2
+ # Monster creature
3
+
4
+ require_relative 'creature'
5
+
6
+ module Gemwarrior
7
+ class Monster < Creature
8
+ attr_accessor :xp, :atk_hi, :atk_lo, :dexterity,
9
+ :rox_to_give, :xp_to_give, :battlecry
10
+
11
+ def initialize(options)
12
+ self.id = options[:id]
13
+ self.name = options[:name]
14
+ self.description = options[:description]
15
+ self.face = options[:face]
16
+ self.hands = options[:hands]
17
+ self.mood = options[:mood]
18
+
19
+ self.level = options[:level]
20
+ self.hp_cur = options[:hp_cur]
21
+ self.hp_max = options[:hp_max]
22
+
23
+ self.atk_lo = options[:atk_lo]
24
+ self.atk_hi = options[:atk_hi]
25
+ self.dexterity = options[:dexterity]
26
+
27
+ self.inventory = options[:inventory]
28
+ self.rox_to_give = options[:rox_to_give]
29
+ self.xp_to_give = options[:xp_to_give]
30
+
31
+ self.battlecry = options[:battlecry]
32
+ end
33
+
34
+ def describe
35
+ status_text = name.upcase.ljust(13)
36
+ status_text << "LEVEL: #{level.to_s.rjust(2)}, "
37
+ status_text << "HP: #{hp_cur.to_s.rjust(3)}/#{hp_max.to_s.rjust(3)}, "
38
+ status_text << "ATK: #{atk_lo.to_s.rjust(2)}-#{atk_hi.to_s.rjust(2)}, "
39
+ status_text << "DEX: #{dexterity.to_s.rjust(3)}, "
40
+ status_text << "XP: #{xp_to_give.to_s.rjust(3)}, "
41
+ status_text << "ROX: #{rox_to_give.to_s.rjust(3)}, "
42
+ status_text << "FACE: #{face.ljust(10)}, "
43
+ status_text << "HANDS: #{hands.ljust(10)}, "
44
+ status_text << "MOOD: #{mood.ljust(10)}\n"
45
+ status_text.to_s
46
+ end
47
+
48
+ def take_damage(dmg)
49
+ self.hp_cur = hp_cur.to_i - dmg.to_i
50
+ end
51
+
52
+ end
53
+ end
@@ -1,4 +1,4 @@
1
- # lib/gemwarrior/player.rb
1
+ # lib/gemwarrior/entities/player.rb
2
2
  # Player creature
3
3
 
4
4
  require_relative 'creature'
@@ -24,46 +24,37 @@ module Gemwarrior
24
24
  ERROR_ATTACK_OPTION_INVALID = 'That won\'t do anything against the monster.'
25
25
 
26
26
  attr_accessor :xp, :stam_cur, :stam_max, :atk_hi, :atk_lo,
27
- :defense, :dexterity, :rox, :cur_loc
27
+ :defense, :dexterity, :rox, :cur_loc,
28
+ :god_mode
28
29
 
29
- def initialize(
30
- level,
31
- xp,
32
- hp_cur,
33
- hp_max,
34
- stam_cur,
35
- stam_max,
36
- atk_lo,
37
- atk_hi,
38
- defense,
39
- dexterity,
40
- inventory,
41
- rox,
42
- cur_loc
43
- )
30
+ def initialize(options)
44
31
  generate_player_identity
45
32
 
46
- self.level = level
47
- self.xp = xp
33
+ self.level = options[:level]
34
+ self.xp = options[:xp]
48
35
 
49
- self.hp_cur = hp_cur
50
- self.hp_max = hp_max
51
- self.stam_cur = stam_cur
52
- self.stam_max = stam_max
36
+ self.hp_cur = options[:hp_cur]
37
+ self.hp_max = options[:hp_max]
38
+ self.stam_cur = options[:stam_cur]
39
+ self.stam_max = options[:stam_max]
53
40
 
54
- self.atk_lo = atk_lo
55
- self.atk_hi = atk_hi
56
- self.defense = defense
57
- self.dexterity = dexterity
41
+ self.atk_lo = options[:atk_lo]
42
+ self.atk_hi = options[:atk_hi]
43
+ self.defense = options[:defense]
44
+ self.dexterity = options[:dexterity]
58
45
 
59
- self.inventory = inventory
60
- self.rox = rox
46
+ self.inventory = options[:inventory]
47
+ self.rox = options[:rox]
61
48
 
62
- self.cur_loc = cur_loc
49
+ self.cur_loc = options[:cur_loc]
50
+
51
+ self.god_mode = false
63
52
  end
64
53
 
65
- def check_self
66
- print_char_pic
54
+ def check_self(show_pic = true)
55
+ if show_pic
56
+ print_char_pic
57
+ end
67
58
 
68
59
  cur_weapon_name = ''
69
60
  if inventory.weapon.nil?
@@ -74,15 +65,16 @@ module Gemwarrior
74
65
  self.atk_hi = inventory.weapon.atk_hi
75
66
  end
76
67
 
77
- self_text = "You check yourself. Currently breathing, wearing clothing, and with a few other specific characteristics: face is #{face}, hands are #{hands}, and general mood is #{mood}.\n\n"
78
- self_text << "NAME: #{name}\n"
68
+ self_text = "NAME: #{name}\n"
79
69
  self_text << "WPN : #{cur_weapon_name}\n"
80
70
  self_text << "LVL : #{level}\n"
81
71
  self_text << "XP : #{xp}\n"
72
+ self_text << "HP : #{hp_cur}|#{hp_max}\n"
82
73
  self_text << "ATK : #{atk_lo}-#{atk_hi}\n"
83
74
  self_text << "DEF : #{defense}\n"
84
75
  self_text << "DEX : #{dexterity}\n"
85
-
76
+ self_text << "GOD : #{god_mode}\n\n"
77
+ self_text << "You check yourself. Currently breathing, wearing clothing, and with a few other specific characteristics: face is #{face}, hands are #{hands}, and general mood is #{mood}.\n"
86
78
  end
87
79
 
88
80
  def rest
@@ -149,60 +141,68 @@ module Gemwarrior
149
141
  new_loc_id = cur_loc.locs_connected[direction.to_sym]
150
142
  self.cur_loc = loc_by_id(locations, new_loc_id)
151
143
  print_traveling_text
152
- cur_loc.checked_for_monsters = false
153
- cur_loc.describe
144
+ self.cur_loc.checked_for_monsters = false
145
+ self.cur_loc.describe
154
146
  else
155
147
  ERROR_GO_PARAM_INVALID
156
148
  end
157
149
  end
158
150
  end
159
-
151
+
160
152
  def attack(monster_name)
161
153
  if cur_loc.has_monster_to_attack?(monster_name)
162
- puts "You decide to attack the #{monster_name}"
154
+ print_battle_line
155
+ puts "You decide to attack the #{monster_name}!"
163
156
  monster = cur_loc.monster_by_name(monster_name)
164
157
  puts "#{monster.name} cries out: #{monster.battlecry}"
165
158
 
159
+ # first strike!
160
+ if calculate_first_strike(monster)
161
+ puts "#{monster.name} strikes first!"
162
+ player_attacked_by(monster)
163
+ end
164
+
165
+ # main battle loop
166
166
  loop do
167
167
  if (monster.hp_cur <= 0)
168
- puts "You have defeated #{monster.name}!"
169
- puts "You have received #{monster.xp_to_give} XP!"
170
- puts "You have gained #{monster.rox} barterable rox!"
171
- update_player_stats(monster)
172
- cur_loc.remove_monster(monster.name)
173
- return
174
- elsif (hp_cur <= 0)
175
- puts "You are dead, slain by the #{monster.name}!"
168
+ monster_death(monster)
176
169
  return
170
+ elsif (hp_cur <= 0 && !god_mode)
171
+ player_death(monster)
177
172
  end
178
-
179
- puts "\nYour options are 'fight', 'look', and 'run'."
173
+
174
+ puts
175
+ puts "[Fight/Attack][Look][Run]"
180
176
  puts "P :: #{hp_cur} HP\n"
181
- puts "E :: #{monster.hp_cur} HP\n"
177
+ puts "M :: #{monster.hp_cur} HP\n"
182
178
 
183
179
  if ((monster.hp_cur.to_f / monster.hp_max.to_f) < 0.10)
184
180
  puts "#{monster.name} is almost dead!\n"
185
181
  end
186
182
 
187
183
  puts 'What do you do?'
188
- cmd = gets.chomp
184
+ cmd = gets.chomp.downcase
189
185
 
186
+ # player action
190
187
  case cmd
191
- when 'fight', 'f'
192
- puts "You attack #{monster.name}#{inventory.weapon}!"
188
+ when 'fight', 'f', 'attack', 'a'
189
+ puts "You attack #{monster.name}#{cur_weapon_name}!"
193
190
  dmg = calculate_mob_damage
194
191
  if dmg > 0
195
192
  puts "You wound it for #{dmg} point(s)!"
196
193
  monster.take_damage(dmg)
194
+ if (monster.hp_cur <= 0)
195
+ monster_death(monster)
196
+ return
197
+ end
197
198
  else
198
199
  puts "You miss entirely!"
199
200
  end
200
201
  when 'look', 'l'
201
202
  puts "#{monster.name}: #{monster.description}"
202
- puts "Its got some distinguishing features, too: face is #{monster.face}, hands are #{monster.hands}, and its general mood is #{monster.mood}."
203
+ puts "Its got some distinguishing features, too: face is #{monster.face}, hands are #{monster.hands}, and general mood is #{monster.mood}."
203
204
  when 'run', 'r'
204
- escape = calculate_escape(monster)
205
- if escape
205
+ if player_escape?(monster)
206
206
  monster.hp_cur = monster.hp_max
207
207
  puts "You successfully elude #{monster.name}!"
208
208
  return
@@ -212,11 +212,49 @@ module Gemwarrior
212
212
  else
213
213
  puts ERROR_ATTACK_OPTION_INVALID
214
214
  end
215
+
216
+ # monster action
217
+ player_attacked_by(monster)
215
218
  end
216
219
  else
217
220
  ERROR_ATTACK_PARAM_INVALID
218
221
  end
219
222
  end
223
+
224
+ private
225
+
226
+ # COMBAT
227
+ def update_player_stats(monster)
228
+ self.xp = xp + monster.xp_to_give
229
+ self.rox = rox + monster.rox_to_give
230
+ end
231
+
232
+ def monster_death(monster)
233
+ puts "You have defeated #{monster.name}!"
234
+ puts "You have received #{monster.xp_to_give} XP!"
235
+ puts "You have found #{monster.rox_to_give} barterable rox on your slain opponent!"
236
+ print_battle_line
237
+ update_player_stats(monster)
238
+ cur_loc.remove_monster(monster.name)
239
+ end
240
+
241
+ def player_death(monster)
242
+ puts "You are dead, slain by the #{monster.name}!"
243
+ puts 'Your adventure ends here. Try again next time!'
244
+ print_battle_line
245
+ exit(0)
246
+ end
247
+
248
+ def player_attacked_by(monster)
249
+ puts "#{monster.name} attacks you!"
250
+ dmg = calculate_player_damage(monster)
251
+ if dmg > 0
252
+ puts "You are wounded for #{dmg} point(s)!"
253
+ take_damage(dmg)
254
+ else
255
+ puts "#{monster.name} misses entirely!"
256
+ end
257
+ end
220
258
 
221
259
  def cur_weapon_name
222
260
  unless inventory.weapon.nil?
@@ -233,7 +271,30 @@ module Gemwarrior
233
271
  end
234
272
  end
235
273
 
236
- def calculate_escape(monster)
274
+ def calculate_player_damage(monster)
275
+ miss = rand(0..100)
276
+ if (miss < 15)
277
+ 0
278
+ else
279
+ rand(monster.atk_lo..monster.atk_hi)
280
+ end
281
+ end
282
+
283
+ def calculate_first_strike(monster)
284
+ if (monster.dexterity > dexterity)
285
+ return true
286
+ else
287
+ dex_diff = dexterity - monster.dexterity
288
+ rand_dex = rand(0..dex_diff)
289
+ if rand_dex % 2 > 0
290
+ return true
291
+ else
292
+ return false
293
+ end
294
+ end
295
+ end
296
+
297
+ def player_escape?(monster)
237
298
  if (dexterity > monster.dexterity)
238
299
  return true
239
300
  else
@@ -246,14 +307,12 @@ module Gemwarrior
246
307
  end
247
308
  end
248
309
  end
249
-
250
- private
251
310
 
252
- def update_player_stats(monster)
253
- self.xp = xp + monster.xp_to_give
254
- self.rox = rox + monster.rox
311
+ def take_damage(dmg)
312
+ self.hp_cur = hp_cur.to_i - dmg.to_i
255
313
  end
256
314
 
315
+ # TRAVEL
257
316
  def print_traveling_text
258
317
  loc = Thread.new do
259
318
  print "* "
@@ -263,6 +322,7 @@ module Gemwarrior
263
322
  loc.join
264
323
  end
265
324
 
325
+ # CHARACTER
266
326
  def print_char_pic
267
327
  char_pic = ""
268
328
  char_pic << "**********\n"
@@ -275,6 +335,7 @@ module Gemwarrior
275
335
  puts char_pic
276
336
  end
277
337
 
338
+ # INIT
278
339
  def generate_name
279
340
  name = []
280
341
  letter_max = rand(5..10)
@@ -309,5 +370,9 @@ module Gemwarrior
309
370
  self.hands = generate_hands
310
371
  self.mood = generate_mood
311
372
  end
373
+
374
+ def print_battle_line
375
+ puts '**************************************'
376
+ end
312
377
  end
313
378
  end