gemwarrior 0.12.5 → 0.12.6

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: 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