gemwarrior 0.12.5 → 0.12.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 87bff5190da68f1454d52814bd9422db83ee0557
4
- data.tar.gz: 20431dada8b12529559d785d9153a7051bb76e2c
3
+ metadata.gz: 300296825e93c873913e9d320b57f60e8fe3b74c
4
+ data.tar.gz: 81572b6003715ae7c1daf54e196c49a18186c68a
5
5
  SHA512:
6
- metadata.gz: 9aaabc538029f95eb443f464c35865eb7cf184880b616058b20dc0402c80a28eb19dac63c627d2fa1c1781c181007e945ed65a867cc56bc6ec475a862806a59d
7
- data.tar.gz: 18d20126876e58d3e74f89ff2e46c0687bcea02281772b5590f2a393ea6cb6e7b0397fc3a22e1526696787907b5ac69e5aa7c3bfac9a6b74181b01b84eb06a91
6
+ metadata.gz: 12a00f13c496e14a5af47b1dc6dbe6ece42ba66035ce9d36646c0971f031eaaba51d5d17f8441fcd24f7735f318ddbfc9e67e9f87aeb9bc75c48e1bc07282f15
7
+ data.tar.gz: 64bb8979dce6de9d1a52483a7ffe91d8c660804f35132d950c7d6c438f6147c352141cfb3613be69cfda0d234df01af184aa6e729baf21c8f30f3712834bde34
@@ -2080,8 +2080,8 @@ player: !ruby/object:Gemwarrior::Player
2080
2080
  hp_max: 30
2081
2081
  atk_lo: 1
2082
2082
  atk_hi: 2
2083
- defense: 5
2084
- dexterity: 5
2083
+ defense: 1
2084
+ dexterity: 1
2085
2085
  inventory: !ruby/object:Gemwarrior::Inventory
2086
2086
  armor:
2087
2087
  items: []
@@ -7,7 +7,14 @@ module Gemwarrior
7
7
  class Battle
8
8
  # CONSTANTS
9
9
  ERROR_ATTACK_OPTION_INVALID = 'That will not do anything against the monster.'
10
- BEAST_MODE_ATTACK = 100
10
+ BEAST_MODE_ATTACK_LO = 100
11
+ BEAST_MODE_ATTACK_HI = 200
12
+ ATTEMPT_SUCCESS_LO_DEFAULT = 0
13
+ ATTEMPT_SUCCESS_HI_DEFAULT = 100
14
+ MISS_CAP_DEFAULT = 20
15
+ LV3_MOD_LO = 6
16
+ LV5_MOD_LO = 7
17
+ LV5_MOD_HI = 14
11
18
  ESCAPE_TEXT = '** POOF **'
12
19
 
13
20
  attr_accessor :world,
@@ -58,7 +65,7 @@ module Gemwarrior
58
65
  monster_attacks_player
59
66
  end
60
67
 
61
- # LV4:STONE_FACE modifier prior to main battle to auto-win
68
+ # LV4:STONE_FACE modifier (chance to auto-win)
62
69
  # Doesn't work against bosses, nor if battle is an event or in the arena
63
70
  if player.special_abilities.include?(:stone_face) && !monster.is_boss && !is_event && !is_arena
64
71
  level_diff = (player.level - monster.level) * 4
@@ -68,8 +75,8 @@ module Gemwarrior
68
75
  if GameOptions.data['debug_mode']
69
76
  puts
70
77
  puts " (MOD) LV4: Stone Face"
71
- puts " Range to auto-win: #{chance_range}"
72
- puts " Auto-win roll: #{roll}"
78
+ puts " SUCCESS_RANGE: #{chance_range}"
79
+ puts " SUCCESS_ROLL : #{roll}"
73
80
  end
74
81
 
75
82
  if chance_range.include?(roll)
@@ -97,11 +104,11 @@ module Gemwarrior
97
104
  puts
98
105
 
99
106
  # print health info
100
- print " #{player.name.upcase.ljust(12)} :: #{player.hp_cur.to_s.rjust(3)} HP"
107
+ print " #{player.name.upcase.ljust(12).colorize(:green)} :: #{player.hp_cur.to_s.rjust(3)} HP"
101
108
  print " (LVL: #{player.level})" if GameOptions.data['debug_mode']
102
109
  print "\n"
103
110
 
104
- print " #{monster.name.upcase.ljust(12)} :: "
111
+ print " #{monster.name.upcase.ljust(12).colorize(:red)} :: "
105
112
  if GameOptions.data['debug_mode'] || player.special_abilities.include?(:rocking_vision)
106
113
  print "#{monster.hp_cur.to_s.rjust(3)}"
107
114
  else
@@ -137,7 +144,7 @@ module Gemwarrior
137
144
 
138
145
  if can_attack
139
146
  puts " You attack #{monster.name}#{player.cur_weapon_name}!"
140
- dmg = calculate_damage_to(monster)
147
+ dmg = calculate_damage(player, monster)
141
148
  if dmg > 0
142
149
  Audio.play_synth(:battle_player_attack)
143
150
 
@@ -149,7 +156,7 @@ module Gemwarrior
149
156
  else
150
157
  Audio.play_synth(:battle_player_miss)
151
158
 
152
- puts ' You miss entirely!'.colorize(:yellow)
159
+ puts ' You do no damage!'.colorize(:yellow)
153
160
  end
154
161
  end
155
162
  when 'defend', 'd'
@@ -233,27 +240,80 @@ module Gemwarrior
233
240
  private
234
241
 
235
242
  # NEUTRAL
236
- def calculate_damage_to(entity)
237
- miss = rand(0..(100 + entity.defense))
238
- if miss < 15
239
- 0
240
- else
241
- if entity.eql?(monster)
242
- # base attack range
243
+ def calculate_damage(attacker, defender)
244
+ # things that modify attack success and damage
245
+ a_dex = attacker.dexterity
246
+ d_dex = defender.dexterity
247
+ d_def = defender.defense
248
+
249
+ # player attacking monster
250
+ if defender.eql?(monster)
251
+ # attack success defined by attacker's and defender's dexterity
252
+ attempt_success_lo = ATTEMPT_SUCCESS_LO_DEFAULT
253
+ attempt_success_hi = ATTEMPT_SUCCESS_HI_DEFAULT
254
+
255
+ # success range to hit based on dexterity
256
+ attempt_success_hi += rand((a_dex)..(a_dex+2))
257
+ attempt_success_hi -= rand((d_dex)..(d_dex+2))
258
+
259
+ # compute attempt success
260
+ attempt = rand(attempt_success_lo..attempt_success_hi)
261
+ miss_cap = MISS_CAP_DEFAULT
262
+
263
+ ######################
264
+ # ACCURACY MODIFIERS #
265
+ # vvvvvvvvvvvvvvvvvv #
266
+ ######################
267
+
268
+ ### LV5:GRANITON modifier (more accuracy)
269
+ if player.special_abilities.include?(:graniton)
270
+ miss_cap -= rand(LV5_MOD_LO..LV5_MOD_HI)
271
+ end
272
+
273
+ ######################
274
+ # ^^^^^^^^^^^^^^^^^^ #
275
+ # ACCURACY MODIFIERS #
276
+ ######################
277
+
278
+ # number to beat for attack success
279
+ success_min = rand(miss_cap..miss_cap + 5)
280
+
281
+ if GameOptions.data['debug_mode']
282
+ puts
283
+ puts ' Player Roll for Attack:'.colorize(:green)
284
+ puts " ATTEMPT_RANGE: #{attempt_success_lo}..#{attempt_success_hi}"
285
+ puts " MUST_BEAT : #{success_min}"
286
+ if attempt > success_min
287
+ puts " ATTEMPT_ROLL : #{attempt.to_s.colorize(:green)}"
288
+ else
289
+ puts " ATTEMPT_ROLL : #{attempt.to_s.colorize(:red)}"
290
+ end
291
+ end
292
+
293
+ # no miss, so attack
294
+ if attempt > success_min
295
+ # base player damage range
243
296
  base_atk_lo = player.atk_lo
244
297
  base_atk_hi = player.atk_hi
245
298
 
299
+ # weapon increases damage range
246
300
  if player.has_weapon_equipped?
247
301
  base_atk_lo += player.inventory.weapon.atk_lo
248
302
  base_atk_hi += player.inventory.weapon.atk_hi
249
303
  end
250
304
 
251
- atk_range = base_atk_lo..base_atk_hi
305
+ # non-modified damage range
306
+ dmg_range = base_atk_lo..base_atk_hi
307
+
308
+ ####################
309
+ # DAMAGE MODIFIERS #
310
+ # vvvvvvvvvvvvvvvv #
311
+ ####################
252
312
 
253
- # DEBUG(beast mode) modifier
313
+ ### DEBUG:BEAST_MODE modifier (ludicrously higher damage range)
254
314
  if GameOptions.data['beast_mode']
255
- atk_range = BEAST_MODE_ATTACK..BEAST_MODE_ATTACK
256
- # LV3:ROCK_SLIDE modifier
315
+ dmg_range = BEAST_MODE_ATTACK_LO..BEAST_MODE_ATTACK_HI
316
+ ### LV3:ROCK_SLIDE modifier (increased damage range)
257
317
  elsif player.special_abilities.include?(:rock_slide)
258
318
  lo_boost = rand(0..9)
259
319
  hi_boost = lo_boost + rand(5..10)
@@ -265,20 +325,114 @@ module Gemwarrior
265
325
  puts " Rock Slide hi_boost: #{hi_boost}"
266
326
  end
267
327
 
268
- if lo_boost >= 6
328
+ if lo_boost >= LV3_MOD_LO
269
329
  puts " You use Rock Slide for added damage!"
270
- atk_range = (player.atk_lo + lo_boost)..(player.atk_hi + hi_boost)
330
+ dmg_range = (player.atk_lo + lo_boost)..(player.atk_hi + hi_boost)
271
331
  else
272
332
  puts " Rock Slide failed :(" if GameOptions.data['debug_mode']
273
333
  end
274
334
  end
275
335
 
276
- # return attack range
277
- return rand(atk_range)
336
+ ####################
337
+ # ^^^^^^^^^^^^^^^^ #
338
+ # DAMAGE MODIFIERS #
339
+ ####################
340
+
341
+ # get base damage to apply
342
+ base_dmg = rand(dmg_range)
343
+
344
+ # lower value due to defender's defense
345
+ dmg = base_dmg - d_def
346
+
347
+ # 50% chance of doing 1 point of damage even if you were going to do no damage
348
+ hail_mary = [dmg, 1].sample
349
+ dmg = hail_mary if dmg <= 0
350
+
351
+ if GameOptions.data['debug_mode']
352
+ puts
353
+ puts ' Player Roll for Damage:'.colorize(:green)
354
+ puts " DMG_RANGE : #{dmg_range}"
355
+ puts " DMG_ROLL : #{base_dmg}"
356
+ puts " MONSTER_DEF: #{d_def}"
357
+ puts " HAIL_MARY : #{hail_mary}"
358
+ if dmg > 0
359
+ puts " NET_DMG : #{dmg.to_s.colorize(:green)}"
360
+ else
361
+ puts " NET_DMG : #{dmg.to_s.colorize(:red)}"
362
+ end
363
+ end
364
+
365
+ return dmg
366
+ # missed? no damage
278
367
  else
279
- dmg = rand(monster.atk_lo..monster.atk_hi)
280
- dmg -= (entity.defense / 2) if player_is_defending
368
+ return 0
369
+ end
370
+ # monster attacking player
371
+ else
372
+ # attack success defined by attacker's and defender's dexterity
373
+ attempt_success_lo = ATTEMPT_SUCCESS_LO_DEFAULT
374
+ attempt_success_hi = ATTEMPT_SUCCESS_HI_DEFAULT
375
+
376
+ # success range to hit based on dexterity
377
+ attempt_success_hi += rand((a_dex)..(a_dex+2))
378
+ attempt_success_hi -= rand((d_dex)..(d_dex+2))
379
+
380
+ # compute attempt success
381
+ attempt = rand(attempt_success_lo..attempt_success_hi)
382
+ miss_cap = MISS_CAP_DEFAULT
383
+
384
+ # number to beat for attack success
385
+ success_min = rand(miss_cap..miss_cap + 5)
386
+
387
+ if GameOptions.data['debug_mode']
388
+ puts
389
+ puts ' Monster Roll for Attack:'.colorize(:red)
390
+ puts " ATTEMPT_RANGE: #{attempt_success_lo}..#{attempt_success_hi}"
391
+ puts " ATTEMPT_ROLL : #{attempt}"
392
+ puts " MUST_BEAT : #{success_min}"
393
+ if attempt > success_min
394
+ puts " ATTEMPT_ROLL : #{attempt.to_s.colorize(:green)}"
395
+ else
396
+ puts " ATTEMPT_ROLL : #{attempt.to_s.colorize(:red)}"
397
+ end
398
+ end
399
+
400
+ # no miss, so attack
401
+ if attempt > success_min
402
+ dmg_range = attacker.atk_lo..attacker.atk_lo
403
+
404
+ # get base damage to apply
405
+ base_dmg = rand(dmg_range)
406
+
407
+ # lower value for defender's defense (and further if actively defending)
408
+ if player_is_defending
409
+ dmg = base_dmg - [(d_def * 1.5).floor, (d_def * 1.5).ceil].sample
410
+ else
411
+ dmg = base_dmg - d_def
412
+ end
413
+
414
+ # 25% chance of doing 1 point of damage even if monster was going to do no damage
415
+ hail_mary = [dmg, dmg, dmg, 1].sample
416
+ dmg = hail_mary if dmg <= 0
417
+
418
+ if GameOptions.data['debug_mode']
419
+ puts
420
+ puts ' Monster Roll for Damage:'.colorize(:red)
421
+ puts " DMG_RANGE : #{dmg_range}"
422
+ puts " DMG_ROLL : #{base_dmg}"
423
+ puts " PLAYER_DEF : #{d_def}"
424
+ puts " HAIL_MARY : #{hail_mary}"
425
+ if dmg > 0
426
+ puts " NET_DMG : #{dmg.to_s.colorize(:green)}"
427
+ else
428
+ puts " NET_DMG : #{dmg.to_s.colorize(:red)}"
429
+ end
430
+ end
431
+
281
432
  return dmg
433
+ # missed? no damage
434
+ else
435
+ return 0
282
436
  end
283
437
  end
284
438
  end
@@ -322,7 +476,7 @@ module Gemwarrior
322
476
  def monster_attacks_player
323
477
  puts " #{monster.name} attacks you!".colorize(:yellow)
324
478
 
325
- dmg = calculate_damage_to(player)
479
+ dmg = calculate_damage(monster, player)
326
480
  if dmg > 0
327
481
  Audio.play_synth(:battle_monster_attack)
328
482
 
@@ -330,7 +484,7 @@ module Gemwarrior
330
484
  else
331
485
  Audio.play_synth(:battle_monster_miss)
332
486
 
333
- puts " #{monster.name} misses entirely!".colorize(:yellow)
487
+ puts " #{monster.name} does no damage!".colorize(:yellow)
334
488
  end
335
489
  end
336
490
 
@@ -11,6 +11,7 @@ module Gemwarrior
11
11
  DANGER_LEVEL = { none: 0, low: 15, moderate: 30, high: 55, assured: 100 }
12
12
  ERROR_ITEM_ADD_INVALID = 'That item cannot be added to the location\'s inventory.'
13
13
  ERROR_ITEM_REMOVE_INVALID = 'That item cannot be removed as it does not exist here.'
14
+ ERROR_SPAWN_NAME_INVALID = 'That monster does not exist in the game, and cannot be spawned.'
14
15
 
15
16
  attr_accessor :coords,
16
17
  :paths,
@@ -193,26 +194,36 @@ module Gemwarrior
193
194
  actionable_words.join(', ')
194
195
  end
195
196
 
196
- def populate_monsters(monsters_available, spawn = false)
197
+ def populate_monsters(monsters_available = nil, spawn = false, monster_type = nil)
197
198
  if should_spawn_monster? || spawn
198
199
  self.checked_for_monsters = true unless spawn
199
200
  self.monsters_abounding = [] unless spawn
200
201
  random_monster = nil
201
202
 
202
- # get random non-boss monster
203
- loop do
204
- random_monster = monsters_available[rand(0..monsters_available.length-1)].clone
203
+ if monster_type.nil?
204
+ # get random non-boss monster
205
+ loop do
206
+ random_monster = monsters_available[rand(0..monsters_available.length-1)].clone
205
207
 
206
- if spawn
207
- break
208
- else
209
- unless random_monster.is_boss || !self.monster_level_range.include?(random_monster.level)
208
+ if spawn
210
209
  break
210
+ else
211
+ unless random_monster.is_boss || !self.monster_level_range.include?(random_monster.level)
212
+ break
213
+ end
211
214
  end
212
215
  end
213
- end
214
216
 
215
- monsters_abounding.push(random_monster)
217
+ monsters_abounding.push(random_monster)
218
+ else
219
+ monster_type_to_spawn = monsters_available.find { |m| m.name.downcase == monster_type.downcase }
220
+ if monster_type_to_spawn.nil?
221
+ puts ERROR_SPAWN_NAME_INVALID.colorize(:red)
222
+ puts
223
+ else
224
+ monsters_abounding.push(monster_type_to_spawn)
225
+ end
226
+ end
216
227
  else
217
228
  return nil
218
229
  end
@@ -21,7 +21,7 @@ module Gemwarrior
21
21
  self.hp_max = hp_cur
22
22
  self.atk_lo = rand(level..(level * 1.5).floor)
23
23
  self.atk_hi = rand((level * 1.5).floor..(level * 2))
24
- self.defense = rand(level..(level * 1.5).floor)
24
+ self.defense = rand(1..2)
25
25
  self.dexterity = rand(1..3)
26
26
 
27
27
  self.rox = rand((level * 2)..(level * 3))
@@ -21,8 +21,8 @@ module Gemwarrior
21
21
  self.hp_max = hp_cur
22
22
  self.atk_lo = rand(level..(level * 2))
23
23
  self.atk_hi = rand((level * 2)..(level * 2.5).floor)
24
- self.defense = rand((level * 2)..(level * 2.5).floor)
25
- self.dexterity = rand(3..4)
24
+ self.defense = rand(2..3)
25
+ self.dexterity = rand(2..4)
26
26
 
27
27
  self.rox = rand((level * 2)..(level * 3))
28
28
  self.xp = rand(level..(level * 2))
@@ -18,7 +18,7 @@ module Gemwarrior
18
18
  self.mood = 'opaque'
19
19
 
20
20
  self.level = rand(7..8)
21
- self.hp_cur = rand((level * 2.5).floor..(level * 3.5).floor)
21
+ self.hp_cur = rand((level * 4.5).floor..(level * 5.5).floor)
22
22
  self.hp_max = hp_cur
23
23
  self.atk_lo = rand((level * 2)..(level * 2.5).floor)
24
24
  self.atk_hi = rand((level * 2.5).floor..(level * 3).floor)
@@ -21,7 +21,7 @@ module Gemwarrior
21
21
  self.hp_max = hp_cur
22
22
  self.atk_lo = rand(level..(level * 2.5).floor)
23
23
  self.atk_hi = rand((level * 2.5).floor..(level * 3).floor)
24
- self.defense = rand(5..7)
24
+ self.defense = rand(6..7)
25
25
  self.dexterity = rand(8..10)
26
26
 
27
27
  self.rox = rand((level * 2)..(level * 3))
@@ -277,7 +277,7 @@ module Gemwarrior
277
277
  end
278
278
  when 'spawn', 'sp'
279
279
  player_cur_location = world.location_by_coords(world.player.cur_coords)
280
- player_cur_location.populate_monsters(GameMonsters.data, spawn: true)
280
+ player_cur_location.populate_monsters(GameMonsters.data, true, param1)
281
281
  return world.describe(player_cur_location)
282
282
  when 'teleport', 'tp'
283
283
  if param1.nil?
@@ -10,7 +10,7 @@ module Gemwarrior
10
10
  level: 1, xp_start: 0,
11
11
  hp_max: 30, stam_max: 20,
12
12
  atk_lo: 1, atk_hi: 2,
13
- defense: 5, dexterity: 5,
13
+ defense: 1, dexterity: 1,
14
14
  special_abilities: nil
15
15
  }
16
16
  when 2
@@ -18,7 +18,7 @@ module Gemwarrior
18
18
  level: 2, xp_start: 50,
19
19
  hp_max: 35, stam_max: 25,
20
20
  atk_lo: 2, atk_hi: 3,
21
- defense: 6, dexterity: 6,
21
+ defense: 3, dexterity: 3,
22
22
  special_abilities: :rocking_vision
23
23
  }
24
24
  when 3
@@ -26,7 +26,7 @@ module Gemwarrior
26
26
  level: 3, xp_start: 120,
27
27
  hp_max: 45, stam_max: 30,
28
28
  atk_lo: 3, atk_hi: 5,
29
- defense: 7, dexterity: 8,
29
+ defense: 5, dexterity: 6,
30
30
  special_abilities: :rock_slide
31
31
  }
32
32
  when 4
@@ -34,7 +34,7 @@ module Gemwarrior
34
34
  level: 4, xp_start: 250,
35
35
  hp_max: 55, stam_max: 35,
36
36
  atk_lo: 5, atk_hi: 6,
37
- defense: 8, dexterity: 9,
37
+ defense: 6, dexterity: 8,
38
38
  special_abilities: :stone_face
39
39
  }
40
40
  when 5
@@ -42,7 +42,7 @@ module Gemwarrior
42
42
  level: 5, xp_start: 600,
43
43
  hp_max: 70, stam_max: 45,
44
44
  atk_lo: 7, atk_hi: 8,
45
- defense: 10, dexterity: 11,
45
+ defense: 8, dexterity: 9,
46
46
  special_abilities: :graniton
47
47
  }
48
48
  when 6
@@ -50,7 +50,7 @@ module Gemwarrior
50
50
  level: 6, xp_start: 1000,
51
51
  hp_max: 85, stam_max: 60,
52
52
  atk_lo: 8, atk_hi: 10,
53
- defense: 13, dexterity: 13,
53
+ defense: 10, dexterity: 11,
54
54
  special_abilities: :gleam
55
55
  }
56
56
  when 7
@@ -58,7 +58,7 @@ module Gemwarrior
58
58
  level: 7, xp_start: 1500,
59
59
  hp_max: 100, stam_max: 80,
60
60
  atk_lo: 10, atk_hi: 12,
61
- defense: 15, dexterity: 16,
61
+ defense: 13, dexterity: 14,
62
62
  special_abilities: :break_through
63
63
  }
64
64
  else
@@ -100,7 +100,8 @@ module Gemwarrior
100
100
  'Adds a random boost to the player\'s attack in battle.'
101
101
  when :stone_face
102
102
  'Chance to auto-win in battle against any non-boss monster (does not work in arena or if ambushed).'
103
- #when :graniton
103
+ when :graniton
104
+ 'Chance to be much more accurate in your attacks.'
104
105
  #when :gleam
105
106
  #when :break_through
106
107
  else
@@ -2,5 +2,5 @@
2
2
  # Version of Gem Warrior
3
3
 
4
4
  module Gemwarrior
5
- VERSION = '0.12.5'
5
+ VERSION = '0.12.6'
6
6
  end
@@ -43,7 +43,7 @@ module Gemwarrior
43
43
  desc_text << "\n >> Path(s): #{point.list_paths.join(', ')}".colorize(:white)
44
44
 
45
45
  if GameOptions.data['debug_mode']
46
- desc_text << "\n >>> Actionable: ".colorize(color: :red, background: :grey)
46
+ desc_text << "\n >>> Actionable: ".colorize(color: :yellow, background: :grey)
47
47
  desc_text << point.list_actionable_words.colorize(color: :white, background: :grey)
48
48
  end
49
49
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemwarrior
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.5
4
+ version: 0.12.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Chadwick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-22 00:00:00.000000000 Z
11
+ date: 2015-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: os