diff --git a/lib/generators/achievement/templates/achievement.rb b/lib/generators/achievement/templates/achievement.rb index aec8989..1f37c56 100644 --- a/lib/generators/achievement/templates/achievement.rb +++ b/lib/generators/achievement/templates/achievement.rb @@ -1,41 +1,92 @@ -class <%= class_name %> < Achievement +class <%= class_name.camelize %> < Achievement - # The required quotas to meet for each achievement level. - # level 1, :quota => 5 - # level 2, :quota => 10 - # level 3, :quota => 30 - # level 4, :quota => 100 - # level 5, :quota => 500 - # Return the value that needs to be checked against the quotas - # set_thing_to_check { |achievable| ... } - - # Comment out below for multi-level achievements - # def self.award_achievements_for(achievable) - # return unless achievable - # levels.each do |level| - # if !achievable.has_achievement?(self, level[:level]) and thing_to_check(achievable) >= level[:quota] - # achievable.award_achievement(self, level[:level]) - # end - # end - # end +## The required quotas to meet for each achievement level. +# level 1, :quota => 5, :points => 50, :imagerank => 'achievement-rank1.png' +# level 2, :quota => 10, :points => 100, :imagerank => 'achievement-rank2.png' +# level 3, :quota => 30, :points => 150, :imagerank => 'achievement-rank3.png' +# level 4, :quota => 100, :points => 200, :imagerank => 'achievement-rank4.png' +# level 5, :quota => 500, :points => 250, :imagerank => 'achievement-rank5.png' + + +## Return the value that needs to be checked against the quotas +# set_thing_to_check { |achievable| } - # Comment out below for once-off achievements - # def self.award_achievements_for(achievable) - # return unless achievable - # return if achievable.has_achievement?(self) - # achievable.award_achievement(self) - # end +## Comment out below for multi-level achievements +# def self.award_achievements_for(achievable, may_lost) +# return unless achievable +# #reload achievable: because may need to be reupdated in case call various in same time +# achievable = achievable.class.base_class.find(achievable.id) +# if achievable +# levels.each do |level| +# if !achievable.has_achievement?(self, level[:level]) and thing_to_check(achievable) >= level[:quota] +# achievable.award_achievement(self, level[:level]) +# elsif may_lost and achievable.has_achievement?(self, level[:level]) and thing_to_check(achievable) < level[:quota] +# achievable.delete_achievement(self) +# end +# end +# end +# end - # Change to reflect the purpose of this achievement. - def self.description - 'An achievement description.' - end +# # Return the boolean value that needs to be checked +# set_thing_to_check { |achievable| boolean } +# +# # Comment out below for once-off achievements +# def self.award_achievements_for(achievable, may_lost) +# return unless achievable +# #reload achievable: because may need to be reupdated in case call various in same time +# achievable = achievable.class.base_class.find(achievable.id) +# if !achievable.has_achievement?(self) and thing_to_check(achievable) +# achievable.award_achievement(self) +# elsif may_lost and achievable.has_achievement?(self) and !thing_to_check(achievable) +# achievable.delete_achievement(self) +# end +# end +# +## Change to reflect the purpose of this achievement. +def title + "Awesome badge" +end + +def first_description + "It's so easy to win this badge, ..." + end +# + def succeed_description + "Congratulations ! ... " + end +# + def next_level_description + if has_next_level? + "For the next level you just have to posseed #{self.class.quota_for(level+1)} badges for the next level (#{self.class.quota_for(level+1) - self.class.thing_to_check(self.achievable)} more than now)" + else + "Yeah, you won the biggest level !" + end + end +# +# # Achievement mode. simple/level + def is_simple + true + end +# + def is_by_level + false + end +# + def simple_points + 10 + end +# # Change the image to use for the achievement. # Be sure to include this file in Rails.root/public/images - def self.image - 'achievement-default.png' + + def image + 'achievement-class_name.png' + end + + def simple_imagerank + 'achievement-simple.png' end end \ No newline at end of file diff --git a/lib/generators/achievement/templates/achievement_observer.rb b/lib/generators/achievement/templates/achievement_observer.rb index 826557e..3a41dd3 100644 --- a/lib/generators/achievement/templates/achievement_observer.rb +++ b/lib/generators/achievement/templates/achievement_observer.rb @@ -1,7 +1,12 @@ -class <%= class_name %>Observer < ActiveRecord::Observer +class <%= class_name.camelize %>Observer < ActiveRecord::Observer observe :<%= model_name.downcase.underscore %> def after_save(<%= model_name.downcase.underscore %>) - <%= class_name %>.award_achievements_for(<%= model_name.downcase.underscore %>.achievable) if ('your conditions here') + <%= class_name.camelize %>.award_achievements_for(<%= model_name.downcase.underscore %>. ???, true) unless <%= model_name.downcase%>.new_record? + end + + +def after_destroy(<%= model_name.downcase.underscore %>) + <%= class_name.camelize %>.award_achievements_for(<%= model_name.downcase.underscore %>. ???, true) unless <%= model_name.downcase%>.new_record? end end \ No newline at end of file diff --git a/lib/generators/paths_of_glory/templates/20100311101933_create_achievements.rb b/lib/generators/paths_of_glory/templates/20100311101933_create_achievements.rb index c0ae954..0ac2a73 100644 --- a/lib/generators/paths_of_glory/templates/20100311101933_create_achievements.rb +++ b/lib/generators/paths_of_glory/templates/20100311101933_create_achievements.rb @@ -9,6 +9,9 @@ def self.up t.string :ref_type t.timestamps + + add_index :achievements, :achievable_id + add_index :achievements, :ref_id end end diff --git a/lib/glory/achievement.rb b/lib/glory/achievement.rb index 042a942..175985f 100644 --- a/lib/glory/achievement.rb +++ b/lib/glory/achievement.rb @@ -13,13 +13,35 @@ def current #scope :order, lambda { |order| {:order => order} } #scope :limit, lambda { |limit| {:limit => limit} } + def points + if is_simple + simple_points + else + self.class.points_for(level) + end + end + + def imagerank + if is_simple + simple_imagerank + else + self.class.imagerank_for(level) + end + end + + # Définit s'il existe un level supérieur à passer. + def has_next_level? + self.class.has_level?(level+1) + end + + class << self def levels @levels ||= [] end def level(level, options = {}) - levels << {:level => level, :quota => options[:quota]} + levels << {:level => level, :quota => options[:quota], :points => options[:points], :imagerank => options[:imagerank]} end def set_thing_to_check(&block) @@ -38,16 +60,20 @@ def quota_for(level) select_level(level)[:quota] if select_level(level) end + def imagerank_for(level) + select_level(level)[:imagerank] if select_level(level) + end + + def points_for(level) + select_level(level)[:points] if select_level(level) + end + def has_level?(level) select_level(level).present? end - def current_level(user) - if current_achievement = user.achievements.kind_of(self).current - current_achievement.level - else - 0 - end + def current_achievement(user) + user.achievements.kind_of(self).current end def next_level(user) @@ -69,5 +95,7 @@ def progress_to_next_level(user) return nil end end + + end end diff --git a/lib/glory/achievements.rb b/lib/glory/achievements.rb index 15596ef..84ce763 100644 --- a/lib/glory/achievements.rb +++ b/lib/glory/achievements.rb @@ -15,11 +15,18 @@ def award_achievement(achievement, level = nil, ref = nil) end def has_achievement?(achievement, level = nil) - conditions = {:type => achievement.to_s, :achievable_id => id, :achievable_type => self.class.to_s} + conditions = {:type => achievement.to_s, :achievable_id => id, :achievable_type => self.class.base_class.to_s} conditions[:level] = level if level achievements.first(:conditions => conditions).present? end + def delete_achievement(achievement, level = nil) + conditions = {:type => achievement.to_s, :achievable_id => id, :achievable_type => self.class.base_class.to_s} + conditions[:level] = level if level + lost_achievement = achievements.first(:conditions => conditions) + lost_achievement.destroy if lost_achievement + end + def get_badges_in_progress(badges) badges.collect do |achievement| {