From eb43c16c8f39f7b889448ed7b2c5c06a5b8e49cf Mon Sep 17 00:00:00 2001 From: jrambold Date: Tue, 17 Jul 2018 06:36:03 -0600 Subject: [PATCH 1/2] Added level and XP to entity and level up formulas --- lib/goby/entity/entity.rb | 47 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/lib/goby/entity/entity.rb b/lib/goby/entity/entity.rb index a8d3b04..08c0eeb 100644 --- a/lib/goby/entity/entity.rb +++ b/lib/goby/entity/entity.rb @@ -18,6 +18,8 @@ class Entity # @option stats [Integer] :attack strength in battle. Set to be positive. # @option stats [Integer] :defense protection from attacks. Set to be positive. # @option stats [Integer] :agility speed of commands in battle. Set to be positive. + # @option stats [Integer] :xp experience used to grow levels. Set to be positive. + # @option stats [Integer] :current level of entity. Set to be positive. # @param [[C(Item, Integer)]] inventory a list of pairs of items and their respective amounts. # @param [Integer] gold the currency used for economical transactions. # @param [Hash] outfit the collection of equippable items currently worn. @@ -154,6 +156,8 @@ def print_status puts "* Attack: #{@stats[:attack]}" puts "* Defense: #{@stats[:defense]}" puts "* Agility: #{@stats[:agility]}" + puts "* Level: #{@stats[:level]}" + puts "* Experience: #{@stats[:xp]}/#{nextLevel(@stats[:level])}" print "\n" puts "Equipment:" @@ -220,8 +224,10 @@ def set_gold(gold) # @option passed_in_stats [Integer] :attack strength in battle. Set to be positive. # @option passed_in_stats [Integer] :defense protection from attacks. Set to be positive. # @option passed_in_stats [Integer] :agility speed of commands in battle. Set to be positive. + # @option passed_in_stats [Integer] :xp experience used to grow levels. Set to be positive. + # @option passed_in_stats [Integer] :current level of entity. Set to be positive. def set_stats(passed_in_stats) - current_stats = @stats || { max_hp: 1, hp: nil, attack: 1, defense: 1, agility: 1 } + current_stats = @stats || { max_hp: 1, hp: nil, attack: 1, defense: 1, agility: 1, xp: 1, level: 1 } constructed_stats = current_stats.merge(passed_in_stats) # Set hp to max_hp if hp not specified @@ -232,14 +238,49 @@ def set_stats(passed_in_stats) constructed_stats[:hp] = constructed_stats[:hp] > 0 ? constructed_stats[:hp] : 0 #ensure all other stats > 0 constructed_stats.each do |key,value| - if [:max_hp, :attack, :defense, :agility].include?(key) + if [:max_hp, :attack, :defense, :agility, :xp, :level].include?(key) constructed_stats[key] = value.nonpositive? ? 1 : value end end - @stats = constructed_stats end + #calculates XP needed to reach the next level + def nextLevel(level) + #set for growth rate + exponent = 1.5 + #set for starting level XP + baseXP = 100 + (baseXP * (level ** exponent)).floor + end + + # checks if player should grow in level based on xp + def check_level + while @stats[:xp] > nextLevel(@stats[:level]) + growLevel + end + end + + # increases stats when growing a level + def grow_level + hp = @stats[max_hp] * perecent_level_growth + attack = @stats[attack] * perecent_level_growth + defense = @stats[defense] * perecent_level_growth + agility = @stats[agility] * perecent_level_growth + xp = @stats[:xp] - nextLevel(@stats[:level]) + if xp <= 0 + xp = 1 + end + level = @stats[:level] + 1 + new_stats = {max_hp: hp, hp: hp, attack: attack, defense: defense, agility: agility, xp: xp, level: level} + set_stats(new_stats) + end + + # defines how much stats should grow per level currently 8-12% + def perecent_level_growth + rand(8..12) * .01 + end + # getter for stats # # @return [Object] From a4200c211407e5049d09f6489f6b4aee8eba9d42 Mon Sep 17 00:00:00 2001 From: jrambold Date: Tue, 17 Jul 2018 07:16:33 -0600 Subject: [PATCH 2/2] Adds XP at the end of a battle and checks for leveling up --- lib/goby/battle/battle.rb | 51 ++++++++++++++++++++++++++++++++++++--- lib/goby/entity/entity.rb | 2 ++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/lib/goby/battle/battle.rb b/lib/goby/battle/battle.rb index fb60a94..0ccb91f 100644 --- a/lib/goby/battle/battle.rb +++ b/lib/goby/battle/battle.rb @@ -37,8 +37,18 @@ def determine_winner end end - #If @entity_a is dead return @entity_b, otherwise return @entity_a - entity_a.stats[:hp] <=0 ? entity_b : entity_a + # If @entity_a is dead set winner to @entity_b, otherwise @entity_a + winner = entity_a.stats[:hp] <=0 ? entity_b : entity_a + # Sets loser to entity with 0 or less hp + loser = entity_a.stats[:hp] <=0 ? entity_a : entity_b + if winner.class != Monster + # Gain XP based on opponent + gain_xp(winner, loser) + # Check if winner can level up + winner.check_level + # return winner + end + winner end private @@ -64,7 +74,42 @@ def someone_dead? entity_a.stats[:hp] <= 0 || entity_b.stats[:hp] <= 0 end + # Gain XP based on defeated opponent + # + # @param [Entity] the winner of the battle + # @param [Entity] the loser of the battle + # @return [Integer] the amount of xp gained + def gain_xp(winner, loser) + # Monsters should not level up fighting players + if winner.class != Monster + # Different Mechanics for monster vs pvp + if loser.class == Monster + # Gain monsters XP + xp = winner[:xp] + loser[:xp] + else + # Calculate XP gain based on level difference + level_diff = winner[:level] - loser[:level] + # About 10 victories to level up + if level_diff == 0 + xp = (winner.nextLevel(winner[:level]) * 0.01).floor + # 10% more XP for each level down + elsif level_diff > 0 + xp = (winner.nextLevel(winner[:level]) * 0.01 * level_diff).floor + else + amount = 0.01-0.001 * level_diff + # Minimum XP gain + if amount <= 0 + amount = 0.001 + end + xp = (winner.nextLevel(winner[:level]) * amount).floor + end + end + winner.set_stats(xp: xp) + end + xp + end + attr_reader :entity_a, :entity_b end -end \ No newline at end of file +end diff --git a/lib/goby/entity/entity.rb b/lib/goby/entity/entity.rb index 08c0eeb..c67eb15 100644 --- a/lib/goby/entity/entity.rb +++ b/lib/goby/entity/entity.rb @@ -246,6 +246,8 @@ def set_stats(passed_in_stats) end #calculates XP needed to reach the next level + # + # @param [Integer] :current level of the entity def nextLevel(level) #set for growth rate exponent = 1.5