diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/characters/rankings_controller.rb | 9 | ||||
-rw-r--r-- | app/controllers/leaderboard_controller.rb | 9 | ||||
-rw-r--r-- | app/models/character.rb | 36 | ||||
-rw-r--r-- | app/models/character_skill.rb | 9 | ||||
-rw-r--r-- | app/views/application/_header.html.erb | 3 | ||||
-rw-r--r-- | app/views/application/components/text/_name_and_title.html.erb | 1 | ||||
-rw-r--r-- | app/views/characters/rankings/index.html.erb | 36 | ||||
-rw-r--r-- | app/views/characters/show.html.erb | 5 | ||||
-rw-r--r-- | app/views/leaderboard/index.html.erb | 95 |
9 files changed, 202 insertions, 1 deletions
diff --git a/app/controllers/characters/rankings_controller.rb b/app/controllers/characters/rankings_controller.rb new file mode 100644 index 0000000..bbae9fc --- /dev/null +++ b/app/controllers/characters/rankings_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Characters::RankingsController < ApplicationController + skip_before_action :authenticate_user! + + def index + @character = Character.find(params[:character_id]) + end +end
\ No newline at end of file diff --git a/app/controllers/leaderboard_controller.rb b/app/controllers/leaderboard_controller.rb new file mode 100644 index 0000000..e6e8543 --- /dev/null +++ b/app/controllers/leaderboard_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class LeaderboardController < ApplicationController + def index + @top_per_skill = Hash[Skill.all.map { |s| [s.name.to_sym, CharacterSkill.top_xp_for(s)] }] + @top_total_xp = Character.top_total_xp + @top_total_level = Character.top_total_level + end +end diff --git a/app/models/character.rb b/app/models/character.rb index 8913f71..a5c871b 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -25,6 +25,22 @@ class Character < ApplicationRecord after_create :create_skills, :set_combat_styles after_create { Hearth.create(character: self) } + def self.sorted_by_total_xp + all.sort_by(&:total_xp).reverse + end + + def self.sorted_by_total_level + all.sort_by(&:total_level).reverse + end + + def self.top_total_xp + sorted_by_total_xp.first(5) + end + + def self.top_total_level + sorted_by_total_level.first(5) + end + def beastslay_level; skill_level("beastslay"); end def fluxseethe_level; skill_level("fluxseethe"); end def havencast_level; skill_level("havencast"); end @@ -41,6 +57,26 @@ class Character < ApplicationRecord def wildscour_level; skill_level("wildscour"); end def worldcall_level; skill_level("worldcall"); end + def total_xp + character_skills.sum(:xp).to_i + end + + def total_level + count = 0 + character_skills.each do |cs| + count += cs.level + end + count + end + + def total_xp_rank + Character.sorted_by_total_xp.map(&:id).index(self.id) + 1 + end + + def total_level_rank + Character.sorted_by_total_level.map(&:id).index(self.id) + 1 + end + def vestige vestige = self.character_items.find_by(item: Item.find_by_gid("vestige")) vestige ? vestige.quantity : 0 diff --git a/app/models/character_skill.rb b/app/models/character_skill.rb index 20468c3..722a371 100644 --- a/app/models/character_skill.rb +++ b/app/models/character_skill.rb @@ -26,6 +26,11 @@ class CharacterSkill < ApplicationRecord 1459475733, 1680697391, 1935475040, 2228899094 ].freeze + def self.top_xp_for(skill, limit: 10) + skill = Skill.find_by_gid(skill) if skill.is_a? String + where(skill: skill).order(xp: :desc, updated_at: :asc).limit(limit) + end + def self.level_for_xp(xp) XP_TOTALS_PER_LEVEL.each_with_index do |total, index| if total > xp @@ -48,6 +53,10 @@ class CharacterSkill < ApplicationRecord total_xp_for_next_level - self.xp end + def rank + CharacterSkill.top_xp_for(self.skill, limit: nil).map(&:character).map(&:id).index(self.character.id) + 1 + end + private def xp_required_for_level(level) level <= 120 ? XP_TOTALS_PER_LEVEL[level - 1] : nil diff --git a/app/views/application/_header.html.erb b/app/views/application/_header.html.erb index 25067f3..38bfcf4 100644 --- a/app/views/application/_header.html.erb +++ b/app/views/application/_header.html.erb @@ -14,6 +14,9 @@ <%= link_to "Items", items_path %> </li> <li class="mr-3"> + <%= link_to "Leaderboard", leaderboard_path %> + </li> + <li class="mr-3"> <%= link_to "Logout", logout_path %> </li> <% else %> diff --git a/app/views/application/components/text/_name_and_title.html.erb b/app/views/application/components/text/_name_and_title.html.erb new file mode 100644 index 0000000..41a4f27 --- /dev/null +++ b/app/views/application/components/text/_name_and_title.html.erb @@ -0,0 +1 @@ +<%= render "application/components/text/title", title: character.active_title %> <%= character.name %> diff --git a/app/views/characters/rankings/index.html.erb b/app/views/characters/rankings/index.html.erb new file mode 100644 index 0000000..8f41bd2 --- /dev/null +++ b/app/views/characters/rankings/index.html.erb @@ -0,0 +1,36 @@ +<h1 class="text-2xl">Rankings for <%= render "application/components/text/name_and_title", character: @character %></h1> + +<div class="my-2"> + <%= link_to "Refresh", character_rankings_path %> +</div> + +<div class="my-2"> + <p>Total Level: <%= @character.total_level %> (Rank <%= @character.total_level_rank %>)</p> + <p>Total XP: <%= @character.total_xp %> (Rank <%= @character.total_xp_rank %>)</p> +</div> + +<div class="my-2"> + <div> + <table class="table-auto"> + <thead> + <tr> + <th class="table-header-padded">Skill</th> + <th class="table-header-padded">Rank</th> + <th class="table-header-padded">Level</th> + <th class="table-header-padded">XP</th> + </tr> + </thead> + <tbody> + <% Skill.all.each do |skill| %> + <% character_skill = @character.character_skills.find_by(skill: skill) %> + <tr> + <td class="table-cell-padded"><%= skill.name %></td> + <td class="table-cell-padded"><%= character_skill.rank %></td> + <td class="table-cell-padded"><%= character_skill.level %></td> + <td class="table-cell-padded"><%= character_skill.xp %></td> + </tr> + <% end %> + </tbody> + </table> + </div> +</div> diff --git a/app/views/characters/show.html.erb b/app/views/characters/show.html.erb index ce1c2db..1b5439a 100644 --- a/app/views/characters/show.html.erb +++ b/app/views/characters/show.html.erb @@ -3,7 +3,10 @@ </h1> <div class="text-lg mb-4"> - <%= link_to "Titles", character_titles_path(@character) %> + <ul class="flex flex-row"> + <li class="mr-2"><%= link_to "Titles", character_titles_path(@character) %></li> + <li class="mr-2"><%= link_to "Rankings", character_rankings_path(@character) %></li> + </ul> </div> <p class="mb-4">First entered the planes diff --git a/app/views/leaderboard/index.html.erb b/app/views/leaderboard/index.html.erb new file mode 100644 index 0000000..006def1 --- /dev/null +++ b/app/views/leaderboard/index.html.erb @@ -0,0 +1,95 @@ +<h1 class="text-2xl">Leaderboard</h1> +<p>These rankings are not meant to declare the best characters, only those +with the most XP. XP is far from the only indicator of achievement in Esoterra.</p> + +<% if current_char %> + <div class="my-2"> + <%= link_to "View rankings for #{current_char.name}", character_rankings_path(current_char) %> + </div> +<% end %> + +<div class="my-2"> + <%= link_to "Refresh", leaderboard_path %> +</div> + +<div class="grid grid-cols-12 gap-2"> + <div class="col-span-12 sm:col-span-6"> + <div> + <h2 class="text-xl">Total Level</h2> + <table class="table-auto"> + <thead> + <tr> + <th class="table-header-padded">Rank</th> + <th class="table-header-padded">Character</th> + <th class="table-header-padded">Total Level</th> + </tr> + </thead> + <tbody> + <% @top_total_level.each_with_index do |c, index| %> + <tr> + <td class="table-cell-padded"><%= index + 1 %></td> + <td class="table-cell-padded"><%= link_to c.name, character_rankings_path(c) %></td> + <td class="table-cell-padded"><%= c.total_level %></td> + </tr> + <% end %> + </tbody> + </table> + </div> + </div> + <div class="col-span-12 sm:col-span-6"> + <div> + <h2 class="text-xl">Total XP</h2> + <table class="table-auto"> + <thead> + <tr> + <th class="table-header-padded">Rank</th> + <th class="table-header-padded">Character</th> + <th class="table-header-padded">Total XP</th> + </tr> + </thead> + <tbody> + <% @top_total_xp.each_with_index do |c, index| %> + <tr> + <td class="table-cell-padded"><%= index + 1 %></td> + <td class="table-cell-padded"><%= link_to c.name, character_rankings_path(c) %></td> + <td class="table-cell-padded"><%= c.total_xp %></td> + </tr> + <% end %> + </tbody> + </table> + </div> + + + </div> +</div> + +<div class="mt-4"> + <h2 class="text-xl">Skill XP Totals</h2> + <div class="grid grid-cols-12 gap-2"> + <% @top_per_skill.each do |skill_name, skill_trainings| %> + <div class="col-span-12 sm:col-span-6"> + <h3 class="text-lg my-1"><%= skill_name %></h3> + <table class="table-auto"> + <thead> + <tr> + <th class="table-header-padded">Rank</th> + <th class="table-header-padded">Character</th> + <th class="table-header-padded">Level</th> + <th class="table-header-padded">XP</th> + </tr> + </thead> + <tbody> + <% skill_trainings.each_with_index do |st, index| %> + <tr> + <td class="table-cell-padded"><%= index + 1 %></td> + <td class="table-cell-padded"><%= link_to st.character.name, character_rankings_path(st.character) %></td> + <td class="table-cell-padded"><%= st.level %></td> + <td class="table-cell-padded"><%= st.xp %></td> + </tr> + <% end %> + </tbody> + </table> + </div> + <% end %> + </div> +</div> |