From 03b8bfa53b02754d7c375690d92ed83c1cd661da Mon Sep 17 00:00:00 2001 From: David Gay Date: Sun, 13 Jun 2021 21:40:42 -0400 Subject: Fix wrong param name in new CharacterController `#set_character` --- app/views/characters/skills/index.html.erb | 176 +++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 app/views/characters/skills/index.html.erb (limited to 'app/views/characters/skills') diff --git a/app/views/characters/skills/index.html.erb b/app/views/characters/skills/index.html.erb new file mode 100644 index 0000000..f13e611 --- /dev/null +++ b/app/views/characters/skills/index.html.erb @@ -0,0 +1,176 @@ +

Skills

+
+ +
+ +

First entered the planes + <%= pluralize((Date.current - @character.created_at.to_date).to_i, "day") %> ago.

+ +

Learned <%= @character.learned_activities.count %> recipe(s) or technique(s).

+ +
+
+

Boons & Banes

+ <% if @character.active_states.any? %> +
    + <% @character.active_states.each do |state| %> +
      <%= state.condition.name %> (expires in <%= distance_of_time_in_words_to_now(state.expires_at)%>)
    + <% end %> +
+ <% else %> +

No boons or banes affect you.

+ <% end %> +
+
+ <% if @character == current_char %> +

Combat Styles

+ <%= form_with url: character_combat_styles_path(character_id: @character) do |f| %> + <%= f.label :offensive_style, "Offensive" %> + <%= f.select :offensive_style, Character.offensive_styles.keys.to_a, selected: @character.offensive_style %> + + <%= f.label :defensive_style, "Defensive" %> + <%= f.select :defensive_style, Character.defensive_styles.keys.to_a, selected: @character.defensive_style %> + + <%= f.submit "Set" %> + <% end %> + <% end %> +
+
+ + +
+
+
+

Combat Statistics

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Wounds<%= @character.wounds %> / <%= @character.max_wounds %>
Max HP<%= @character.max_hp %>
Speed<%= @character.speed %>
Accuracy<%= @character.accuracy(with_combat_style: true) %>
Power<%= @character.power(with_combat_style: true) %>
Evasion<%= @character.evasion(with_combat_style: true) %>
+
+
+

Resistances

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Slash<%= @character.resistance("slash")%>
Pierce<%= @character.resistance("pierce") %>
Bash<%= @character.resistance("bash") %>
Arcane<%= @character.resistance("arcane") %>
Fire<%= @character.resistance("fire") %>
Frost<%= @character.resistance("frost") %>
Lightning<%= @character.resistance("lightning") %>
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Acid<%= @character.resistance("acid") %>
Thunder<%= @character.resistance("thunder")%>
Radiant<%= @character.resistance("radiant") %>
Necrotic<%= @character.resistance("necrotic") %>
Poison<%= @character.resistance("poison") %>
Bleed<%= @character.resistance("bleed") %>
+
+
+
+
+
+ +
+

Skills

+ + + + + + + + + + + + <% @character.character_skills.ordered_by_skill_name.each do |cs| %> + + + + + + + <% end %> + +
SkillLevelXPTNLTotal XP
<%= cs.skill.name %><%= cs.level %><%= cs.xp_to_next_level %><%= cs.xp %>
+
+ +<% if @character == current_char %> + <%= link_to "Manage account", edit_user_registration_path, class: "text-sm" %> +<% end %> -- cgit v1.2.3 From d349eaa9ce4700f5c71f7266dbbaaceade9dd7c1 Mon Sep 17 00:00:00 2001 From: David Gay Date: Sun, 13 Jun 2021 22:18:43 -0400 Subject: Move skills to their own page, with a new interface and XP bars --- CHANGELOG.md | 3 + app/models/character_skill.rb | 16 ++- app/views/application/_navbar.html.erb | 3 + app/views/characters/show.html.erb | 25 ---- app/views/characters/skills/index.html.erb | 190 +++-------------------------- config/routes.rb | 1 + 6 files changed, 37 insertions(+), 201 deletions(-) (limited to 'app/views/characters/skills') diff --git a/CHANGELOG.md b/CHANGELOG.md index c49e520..0e8872f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ All notable changes to this project will be documented in this file. ### Hearth - New amenity: binding array (level 1, level 2) +### UI +- Character skills were moved to their own view, which features a new interface with XP bars. + ## [0.1.10.2] - 2021-06-10 ### Activities diff --git a/app/models/character_skill.rb b/app/models/character_skill.rb index 368cc28..406cade 100644 --- a/app/models/character_skill.rb +++ b/app/models/character_skill.rb @@ -39,6 +39,10 @@ class CharacterSkill < ApplicationRecord end end + def self.xp_required_for_level(level) + level <= 120 ? XP_TOTALS_PER_LEVEL[level - 1] : nil + end + def level XP_TOTALS_PER_LEVEL.each_with_index do |total, index| return index if total > self.xp @@ -46,7 +50,7 @@ class CharacterSkill < ApplicationRecord end def total_xp_for_next_level - xp_required_for_level(level + 1) + CharacterSkill.xp_required_for_level(level + 1) end def xp_to_next_level @@ -57,11 +61,13 @@ class CharacterSkill < ApplicationRecord 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 - end + def percentage_of_skill_level_completed + xp_gained_this_level = xp - CharacterSkill.xp_required_for_level(level) + total_xp_gain_neeeded_for_entire_level = total_xp_for_next_level - CharacterSkill.xp_required_for_level(level) + (xp_gained_this_level.to_f / total_xp_gain_neeeded_for_entire_level) * 100 + end + private def send_chat_message_if_leveled_up if CharacterSkill.level_for_xp(self.xp_was) < CharacterSkill.level_for_xp(self.xp) chat_message = ChatMessage.new(body: "reached #{self.skill.name} level #{self.level}!", diff --git a/app/views/application/_navbar.html.erb b/app/views/application/_navbar.html.erb index be2d9f2..3436619 100644 --- a/app/views/application/_navbar.html.erb +++ b/app/views/application/_navbar.html.erb @@ -6,6 +6,9 @@
  • <%= link_to "Character", character_path(current_char) %>
  • +
  • + <%= link_to "Skills", character_skills_path(current_char) %> +
  • <%= link_to "Inventory", character_items_path(current_char) %>
  • diff --git a/app/views/characters/show.html.erb b/app/views/characters/show.html.erb index a7b7c0e..02f2f55 100644 --- a/app/views/characters/show.html.erb +++ b/app/views/characters/show.html.erb @@ -149,31 +149,6 @@ -
    -

    Skills

    - - - - - - - - - - - - <% @character.character_skills.ordered_by_skill_name.each do |cs| %> - - - - - - - <% end %> - -
    SkillLevelXPTNLTotal XP
    <%= cs.skill.name %><%= cs.level %><%= cs.xp_to_next_level %><%= cs.xp %>
    -
    - <% if @character == current_char %> <%= link_to "Manage account", edit_user_registration_path, class: "text-sm" %> <% end %> diff --git a/app/views/characters/skills/index.html.erb b/app/views/characters/skills/index.html.erb index f13e611..fd53870 100644 --- a/app/views/characters/skills/index.html.erb +++ b/app/views/characters/skills/index.html.erb @@ -1,176 +1,24 @@ -

    Skills

    -
    -
      -
    • <%= link_to "Rankings", character_rankings_path(@character) %>
    • -
    • <%= link_to "Titles", character_titles_path(@character) %>
    • -
    -
    - -

    First entered the planes - <%= pluralize((Date.current - @character.created_at.to_date).to_i, "day") %> ago.

    - -

    Learned <%= @character.learned_activities.count %> recipe(s) or technique(s).

    - -
    -
    -

    Boons & Banes

    - <% if @character.active_states.any? %> -
      - <% @character.active_states.each do |state| %> -
        <%= state.condition.name %> (expires in <%= distance_of_time_in_words_to_now(state.expires_at)%>)
      - <% end %> -
    - <% else %> -

    No boons or banes affect you.

    - <% end %> -
    -
    - <% if @character == current_char %> -

    Combat Styles

    - <%= form_with url: character_combat_styles_path(character_id: @character) do |f| %> - <%= f.label :offensive_style, "Offensive" %> - <%= f.select :offensive_style, Character.offensive_styles.keys.to_a, selected: @character.offensive_style %> - - <%= f.label :defensive_style, "Defensive" %> - <%= f.select :defensive_style, Character.defensive_styles.keys.to_a, selected: @character.defensive_style %> - - <%= f.submit "Set" %> - <% end %> - <% end %> -
    -
    - - -
    -
    -
    -

    Combat Statistics

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Wounds<%= @character.wounds %> / <%= @character.max_wounds %>
    Max HP<%= @character.max_hp %>
    Speed<%= @character.speed %>
    Accuracy<%= @character.accuracy(with_combat_style: true) %>
    Power<%= @character.power(with_combat_style: true) %>
    Evasion<%= @character.evasion(with_combat_style: true) %>
    -
    -
    -

    Resistances

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Slash<%= @character.resistance("slash")%>
    Pierce<%= @character.resistance("pierce") %>
    Bash<%= @character.resistance("bash") %>
    Arcane<%= @character.resistance("arcane") %>
    Fire<%= @character.resistance("fire") %>
    Frost<%= @character.resistance("frost") %>
    Lightning<%= @character.resistance("lightning") %>
    +

    Skills

    +
    + <% @character.character_skills.ordered_by_skill_name.each do |cs| %> +
    +
    +
    +
    + <%= cs.skill.name %> +
    +
    + XP<%= cs.xp %> +
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Acid<%= @character.resistance("acid") %>
    Thunder<%= @character.resistance("thunder")%>
    Radiant<%= @character.resistance("radiant") %>
    Necrotic<%= @character.resistance("necrotic") %>
    Poison<%= @character.resistance("poison") %>
    Bleed<%= @character.resistance("bleed") %>
    +
    + <%= cs.level %> +
    +
    +
    +
    -
    -
    - -
    -

    Skills

    - - - - - - - - - - - - <% @character.character_skills.ordered_by_skill_name.each do |cs| %> - - - - - - - <% end %> - -
    SkillLevelXPTNLTotal XP
    <%= cs.skill.name %><%= cs.level %><%= cs.xp_to_next_level %><%= cs.xp %>
    + <% end %>
    - -<% if @character == current_char %> - <%= link_to "Manage account", edit_user_registration_path, class: "text-sm" %> -<% end %> diff --git a/config/routes.rb b/config/routes.rb index fa6d748..22b8299 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,6 +32,7 @@ Rails.application.routes.draw do post "/equip", to: "items#equip" post "/use", to: "items#use" end + resources :skills, only: [:index] resources :titles, only: [:index] do post "/activate", to: "titles#activate" end -- cgit v1.2.3 From 53c9df5feb8ad4ebef8f40840d29255a81edb6df Mon Sep 17 00:00:00 2001 From: David Gay Date: Tue, 15 Jun 2021 19:13:55 -0400 Subject: Reboot omens and allow infixing items (like omens) into skills --- app/controllers/characters/hearth_controller.rb | 3 + .../characters/item_infixes_controller.rb | 27 ++++ app/errors/item_infix_error.rb | 2 + app/models/character.rb | 19 +++ app/models/item.rb | 7 + app/views/characters/items/index.html.erb | 4 + app/views/characters/skills/_infix_slot.html.erb | 3 + app/views/characters/skills/index.html.erb | 59 ++++++-- config/routes.rb | 1 + data/activities.yml | 166 +-------------------- data/conditions.yml | 1 + data/items.yml | 30 ++-- 12 files changed, 127 insertions(+), 195 deletions(-) create mode 100644 app/controllers/characters/item_infixes_controller.rb create mode 100644 app/errors/item_infix_error.rb create mode 100644 app/views/characters/skills/_infix_slot.html.erb (limited to 'app/views/characters/skills') diff --git a/app/controllers/characters/hearth_controller.rb b/app/controllers/characters/hearth_controller.rb index 82f72d6..c525add 100644 --- a/app/controllers/characters/hearth_controller.rb +++ b/app/controllers/characters/hearth_controller.rb @@ -7,6 +7,7 @@ class Characters::HearthController < ApplicationController forge: [], laboratory: [], spicebench: [], + binding_array: [], } Activity.where("gid like ?", "craft_%").each do |activity| @@ -20,6 +21,8 @@ class Characters::HearthController < ApplicationController @amenity_activities[:laboratory].push(activity) && next when "spicebench" @amenity_activities[:spicebench].push(activity) && next + when "binding_array" + @amenity_activities[:binding_array].push(activity) && next else raise "Invalid amenity gid (#{requirement_data[:gid]}" end diff --git a/app/controllers/characters/item_infixes_controller.rb b/app/controllers/characters/item_infixes_controller.rb new file mode 100644 index 0000000..0b5f1c5 --- /dev/null +++ b/app/controllers/characters/item_infixes_controller.rb @@ -0,0 +1,27 @@ +class Characters::ItemInfixesController < ApplicationController + def create + # TODO: Can this find-by-id happen automagically? + @item_infix = current_char.infix(Item.find(params[:item_id]), Skill.find(params[:skill_id])) + if @item_infix + flash[:notice] = "Infixed #{@item_infix.item.name}." + else + flash[:alert] = "Failed to infix item." + end + redirect_to character_skills_path(current_char) + end + + def destroy + @item_infix = ItemInfix.find(params[:id]) + if current_char.remove_infix(@item_infix) + flash[:notice] = "Removed #{@item_infix.item.name}." + else + flash[:alert] = "Failed to remove #{@item_infix.item.name}." + end + redirect_to character_skills_path(current_char) + end + + private + def item_infix_params + params.require(:item_infix).permit(:item_id, :skill_id) + end +end diff --git a/app/errors/item_infix_error.rb b/app/errors/item_infix_error.rb new file mode 100644 index 0000000..bc6b251 --- /dev/null +++ b/app/errors/item_infix_error.rb @@ -0,0 +1,2 @@ +class ItemInfixError < StandardError +end diff --git a/app/models/character.rb b/app/models/character.rb index 03bd510..4ee1f71 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -188,6 +188,25 @@ class Character < ApplicationRecord 1 + (skill_level(skill) / 20).floor end + def available_infixes(skill) + skill = Skill.find_by_gid(skill) if skill.is_a? String + max_infixes(skill) - item_infixes.where(skill: skill).count + end + + def infix(item, skill) + Character.transaction do + shift_item(item, -1) + item_infixes.create(item: item, skill: skill) + end + end + + def remove_infix(item_infix) + Character.transaction do + shift_item(item_infix.item, 1) + item_infix.destroy + end + end + def add_skill_xp(skill, amount) skill = Skill.find_by_gid(skill) if skill.is_a? String Character.transaction do diff --git a/app/models/item.rb b/app/models/item.rb index 8b80788..0e25b2f 100644 --- a/app/models/item.rb +++ b/app/models/item.rb @@ -13,6 +13,13 @@ class Item < ApplicationRecord self.whatnot && self.whatnot[:use_effects]&.any? end + def infixable?(skill = nil) + skill = Skill.find_by_gid(skill) if skill.is_a? String + return false unless self.whatnot && self.whatnot[:infix_skills]&.any? + return true unless skill + self.whatnot[:infix_skills].select { |data| data[:gid] == skill.gid }.any? + end + def equip_slots return [] unless self.equipment? self.whatnot[:equip_slots].map { |data| data.to_sym } diff --git a/app/views/characters/items/index.html.erb b/app/views/characters/items/index.html.erb index 671e68f..57e8531 100644 --- a/app/views/characters/items/index.html.erb +++ b/app/views/characters/items/index.html.erb @@ -35,6 +35,10 @@ character_items: @character.character_items.ordered_by_item_name.select { |ci| ci.item.has_tag?("currency") } %> +<%= render "characters/items/inventory_section", heading: "Omens", + character_items: @character.character_items.ordered_by_item_name.select { |ci| + ci.item.has_tag?("omen") } %> + <%= render "characters/items/inventory_section", heading: "Seeds", character_items: @character.character_items.ordered_by_item_name.select { |ci| ci.item.has_tag?("seed") } %> diff --git a/app/views/characters/skills/_infix_slot.html.erb b/app/views/characters/skills/_infix_slot.html.erb new file mode 100644 index 0000000..0113596 --- /dev/null +++ b/app/views/characters/skills/_infix_slot.html.erb @@ -0,0 +1,3 @@ +
    + <%= yield %> +
    diff --git a/app/views/characters/skills/index.html.erb b/app/views/characters/skills/index.html.erb index fd53870..f79b06e 100644 --- a/app/views/characters/skills/index.html.erb +++ b/app/views/characters/skills/index.html.erb @@ -1,23 +1,56 @@

    Skills

    <% @character.character_skills.ordered_by_skill_name.each do |cs| %> -
    -
    -
    -
    - <%= cs.skill.name %> +
    +
    +
    +
    +
    + <%= cs.skill.name %> +
    +
    + XP<%= cs.xp %> +
    -
    - XP<%= cs.xp %> +
    + <%= cs.level %>
    -
    - <%= cs.level %> -
    -
    -
    -
    +
    +
    +
    + <% @character.item_infixes.where(skill: cs.skill).each do |ii| %> + <%= render "characters/skills/infix_slot" do %> +
    + <%= ii.item.name %> +
    +
    + <%= button_to "Remove", character_item_infix_path(id: ii.id), method: :delete %> +
    + <% end %> + <% end %> + <% @character.available_infixes(cs.skill).times do %> + <%= render "characters/skills/infix_slot" do %> + <%# TODO: Don't load all into memory %> + <% infixable_items = @character.items.select {|i| i.infixable?(cs.skill)} %> + <% if infixable_items.any? %> + <%= form_with url: character_item_infixes_path, class: "w-full" do |f| %> +
    +
    + <%= f.select :item_id, infixable_items.map { |i| [i.name, i.id]}, {}, class: "w-full" %> + <%= f.hidden_field :skill_id, value: cs.skill.id %> +
    +
    + <%= f.submit "Infix" %> +
    +
    + <% end %> + <% else %> +
    No items to infix.
    + <% end %> + <% end %> + <% end %>
    <% end %> diff --git a/config/routes.rb b/config/routes.rb index 22b8299..51d9e6c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -28,6 +28,7 @@ Rails.application.routes.draw do scope module: :characters do get "/rankings", to: "rankings#index" post "/items/unequip/:slot", to: "items#unequip", as: :item_unequip + resources :item_infixes, only: [:create, :destroy] resources :items, only: [:index] do post "/equip", to: "items#equip" post "/use", to: "items#use" diff --git a/data/activities.yml b/data/activities.yml index 525905a..a508781 100644 --- a/data/activities.yml +++ b/data/activities.yml @@ -305,7 +305,7 @@ construct_binding_array_level2: gid: "tourmaline" quantity: 2 - type: "item" - gid: "paraiba tourmaline" + gid: "paraiba_tourmaline" quantity: 1 - type: "item" gid: "yellow_beryl" @@ -2710,9 +2710,9 @@ beastslay_leviathan_floret_region: - type: "monster_spawn" location: "floret_region" chance: 1 -craft_faint_hope: - name: "Bind faint hope" - description: "Bind an omen of faint hope." +craft_faint_mana: + name: "Bind faint mana" + description: "Bind an omen of faint mana." whatnot: requirements: - type: "hearth_amenity" @@ -2737,163 +2737,7 @@ craft_faint_hope: quantity: 10 results: - type: "item" - gid: "faint_hope" + gid: "faint_mana" xp: - gid: "omenbind" value: 6 -craft_fleeting_glimpse: - name: "Bind fleeting glimpse" - description: "Bind a fleeting glimpse omen." - whatnot: - requirements: - - type: "hearth_amenity" - gid: "binding_array" - level: 1 - - type: "skill" - gid: "omenbind" - level: 3 - duration: - base: 65 - minimum: 35 - scaling: - - type: "skill" - gid: "omenbind" - scale_value: 1 - - type: "stat" - gid: "omenbind_speed" - scale_value: 1 - cost: - - type: "item" - gid: "vestige" - quantity: 8 - - type: "item" - gid: "shimmering_essence" - quantity: 1 - results: - - type: "item" - gid: "fleeting_glimpse" - xp: - - gid: "omenbind" - value: 12 -craft_bright_token: - name: "Bind bright token" - description: "Bind a bright token omen." - whatnot: - requirements: - - type: "hearth_amenity" - gid: "binding_array" - level: 1 - - type: "skill" - gid: "omenbind" - level: 6 - duration: - base: 70 - minimum: 35 - scaling: - - type: "skill" - gid: "omenbind" - scale_value: 1 - - type: "stat" - gid: "omenbind_speed" - scale_value: 1 - cost: - - type: "item" - gid: "vestige" - quantity: 12 - - type: "item" - gid: "gem_dust" - quantity: 1 - results: - - type: "item" - gid: "bright_token" - xp: - - gid: "omenbind" - value: 16 -craft_sign_of_solace: - name: "Bind sign of solace" - description: "Bind a sign of solace." - whatnot: - requirements: - - type: "hearth_amenity" - gid: "binding_array" - level: 2 - - type: "skill" - gid: "omenbind" - level: 10 - duration: - base: 80 - minimum: 35 - scaling: - - type: "skill" - gid: "omenbind" - scale_value: 1 - - type: "stat" - gid: "omenbind_speed" - scale_value: 1 - cost: - - type: "item" - gid: "vestige" - quantity: 25 - - type: "item" - gid: "claritas_flower" - quantity: 1 - results: - - type: "item" - gid: "sign_of_solace" - xp: - - gid: "omenbind" - value: 22 -havencast_light: - name: "Cast Light" - description: "Cast the Light cantrip." - whatnot: - tags: - - "cantrip" - duration: - base: 30 - minimum: 10 - scaling: - - type: "skill" - gid: "havencast" - scale_value: 1 - requirements: - - type: "skill" - gid: "havencast" - level: 1 - cost: - - type: "mana" - gid: "clear" - quantity: 1 - results: - - type: "condition" - gid: "light" - - type: "xp" - gid: "havencast" - base: 3 -havencast_dazzle: - name: "Cast Dazzle" - description: "Cast the Dazzle cantrip." - whatnot: - tags: - - "cantrip" - duration: - base: 32 - minimum: 10 - scaling: - - type: "skill" - gid: "havencast" - scale_value: 1 - requirements: - - type: "skill" - gid: "havencast" - level: 2 - cost: - - type: "mana" - gid: "clear" - quantity: 2 - results: - - type: "condition" - gid: "dazzle" - - type: "xp" - gid: "havencast" - base: 6 diff --git a/data/conditions.yml b/data/conditions.yml index 11dcede..3badf5b 100644 --- a/data/conditions.yml +++ b/data/conditions.yml @@ -106,6 +106,7 @@ light: dazzle: name: "dazzle" description: "Reduces enemies' accuracy." + whatnot: effects: - type: "enemy_stat_change" gid: "accuracy" diff --git a/data/items.yml b/data/items.yml index 1f0be2c..224aac6 100644 --- a/data/items.yml +++ b/data/items.yml @@ -1094,27 +1094,15 @@ balgoloth_claw: gid: "pierce" min: 1 max: 6 -faint_hope: - name: "faint hope" - description: "A weak omen made from compressed arcane energy." - whatnot: - tags: - - "omen" -fleeting_glimpse: - name: "fleeting glimpse" - description: "A weak omen that shows vague images in its ethereal surface." - whatnot: - tags: - - "omen" -bright_token: - name: "bright token" - description: "An omen with promising magical potential." - whatnot: - tags: - - "omen" -sign_of_solace: - name: "sign of solace" - description: "A sign that shines radiantly from a pinpoint at its center." +faint_mana: + name: "faint mana" + description: "A weak omen that provides a very small amount of magical energy." whatnot: tags: - "omen" + infix_skills: + - gid: "havencast" + infix_effects: + - type: "stat_change" + gid: "mana" + modifier: 1 -- cgit v1.2.3 From d2a31e04d19796a600a932a3491e056fe2c89af2 Mon Sep 17 00:00:00 2001 From: David Gay Date: Tue, 15 Jun 2021 19:54:29 -0400 Subject: Basic spellcasting --- app/controllers/characters/spells_controller.rb | 5 ++++ app/lib/activity_processor.rb | 7 ++++++ app/models/character.rb | 6 ++++- app/models/concerns/has_costs_and_requirements.rb | 2 ++ app/models/item_infix.rb | 4 ++++ app/views/application/_navbar.html.erb | 3 +++ app/views/application/_results.html.erb | 2 ++ app/views/characters/skills/index.html.erb | 2 +- app/views/characters/spells/index.html.erb | 10 ++++++++ config/routes.rb | 1 + data/activities.yml | 29 +++++++++++++++++++++++ 11 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 app/controllers/characters/spells_controller.rb create mode 100644 app/views/characters/spells/index.html.erb (limited to 'app/views/characters/skills') diff --git a/app/controllers/characters/spells_controller.rb b/app/controllers/characters/spells_controller.rb new file mode 100644 index 0000000..9694856 --- /dev/null +++ b/app/controllers/characters/spells_controller.rb @@ -0,0 +1,5 @@ +class Characters::SpellsController < ApplicationController + def index + @spell_activities = Activity.where("gid like ?", "havencast_%").order(:name) + end +end diff --git a/app/lib/activity_processor.rb b/app/lib/activity_processor.rb index 4a06a98..9b03f55 100644 --- a/app/lib/activity_processor.rb +++ b/app/lib/activity_processor.rb @@ -90,6 +90,13 @@ class ActivityProcessor item = Item.find_by_gid(result[:gid]) hp = @character.hearth.hearth_plantings.create(item: item) @results.push({ type: type, hearth_planting: hp }) + when "condition" + Character.transaction do + condition = Condition.find_by_gid(result[:gid]) + @character.states.create!(condition: condition, expires_at: Time.now + result[:duration]) + @results.push({ type: "message", body: result[:message] }) + @results.push({ type: type, condition: condition }) + end when "activity" next if rand > (result[:chance] || 1) table_roll = rand diff --git a/app/models/character.rb b/app/models/character.rb index 4ee1f71..5ff067c 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -273,6 +273,9 @@ class Character < ApplicationRecord case requirement[:type] when "equipment" return false unless self.equipment_with_gid(requirement[:gid]) + when "stat" + # TODO: HACK: This won't work with built-in stats! Need to change this to work with power and whatnot. + return false unless self.total_stat_change(requirement[:gid]) >= requirement[:value] when "skill" return false unless self.skill_level(requirement[:gid]) >= requirement[:level] when "hearth_amenity" @@ -331,7 +334,8 @@ class Character < ApplicationRecord hearth_amenity_effects = self.hearth.built_hearth_amenities.filter_map { |a| a.effects if a.effects } equipment_effects = self.equipment.filter_map { |a| a.effects if a.effects } state_effects = self.states.filter_map { |a| a.effects if a.effects && !a.expired? } - (hearth_amenity_effects + equipment_effects + state_effects).flatten + item_infix_effects = self.item_infixes.filter_map { |a| a.effects if a.effects } + (hearth_amenity_effects + equipment_effects + state_effects + item_infix_effects).flatten end def total_stat_change(gid) diff --git a/app/models/concerns/has_costs_and_requirements.rb b/app/models/concerns/has_costs_and_requirements.rb index 34ff0f3..9f859f5 100644 --- a/app/models/concerns/has_costs_and_requirements.rb +++ b/app/models/concerns/has_costs_and_requirements.rb @@ -19,6 +19,8 @@ module HasCostsAndRequirements case req[:type] when "skill" requirements.push "level #{req[:level]} #{Skill.find_by_gid(req[:gid]).name}" + when "stat" + requirements.push "#{req[:value]} #{req[:gid]}" when "equipment" requirements.push "equipped #{Item.find_by_gid(req[:gid]).name}" when "hearth_amenity" diff --git a/app/models/item_infix.rb b/app/models/item_infix.rb index cc99ee7..3167320 100644 --- a/app/models/item_infix.rb +++ b/app/models/item_infix.rb @@ -5,6 +5,10 @@ class ItemInfix < ApplicationRecord before_create :check_max_infixes + def effects + self.item.whatnot[:infix_effects] + end + private def check_max_infixes current_infixes = character.item_infixes.where(skill: skill) diff --git a/app/views/application/_navbar.html.erb b/app/views/application/_navbar.html.erb index 3436619..aaec030 100644 --- a/app/views/application/_navbar.html.erb +++ b/app/views/application/_navbar.html.erb @@ -12,6 +12,9 @@
  • <%= link_to "Inventory", character_items_path(current_char) %>
  • +
  • + <%= link_to "Spells", character_spells_path(current_char) %> +
  • <%= link_to "Hearth", character_hearth_path(current_char) %>
  • diff --git a/app/views/application/_results.html.erb b/app/views/application/_results.html.erb index ec62991..691f1d5 100644 --- a/app/views/application/_results.html.erb +++ b/app/views/application/_results.html.erb @@ -24,6 +24,8 @@

    You gained <%= result[:xp] %> <%= result[:skill].name %> XP.

    <% when "title" %>

    You earned the title <%= render "application/components/text/title", title: result[:title] %>!

    + <% when "condition" %> +

    You gained the <%= result[:condition].name %> condition.

    <% when "message" %>

    <%= result[:body] %>

    <% when "warning" %> diff --git a/app/views/characters/skills/index.html.erb b/app/views/characters/skills/index.html.erb index f79b06e..d804384 100644 --- a/app/views/characters/skills/index.html.erb +++ b/app/views/characters/skills/index.html.erb @@ -47,7 +47,7 @@
    <% end %> <% else %> -
    No items to infix.
    +
    No omens to infix.
    <% end %> <% end %> <% end %> diff --git a/app/views/characters/spells/index.html.erb b/app/views/characters/spells/index.html.erb new file mode 100644 index 0000000..5f415a3 --- /dev/null +++ b/app/views/characters/spells/index.html.erb @@ -0,0 +1,10 @@ +

    Spells

    +
    + <%= form_with url: start_activity_path, method: :post do |f| %> + <%= f.select :id, @spell_activities.map { |a| [a.name, a.id] }, {}, + { data: { activity_select_target: "select", action: "activity-select#load" } } %> + <%= f.number_field :actions, value: 1, size: 5, min: 1, max: 2_000_000_000 %> + <%= f.submit "Cast" %> + <% end %> +
    +
    diff --git a/config/routes.rb b/config/routes.rb index 51d9e6c..af608e5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -34,6 +34,7 @@ Rails.application.routes.draw do post "/use", to: "items#use" end resources :skills, only: [:index] + resources :spells, only: [:index] resources :titles, only: [:index] do post "/activate", to: "titles#activate" end diff --git a/data/activities.yml b/data/activities.yml index a508781..ec82b38 100644 --- a/data/activities.yml +++ b/data/activities.yml @@ -2741,3 +2741,32 @@ craft_faint_mana: xp: - gid: "omenbind" value: 6 +havencast_light: + name: "Cast Light" + description: "Risk a little light." + whatnot: + tags: + - "spell" + - "cantrip" + duration: + base: 30 + minimum: 10 + scaling: + - type: "skill" + gid: "havencast" + scale_value: 1 + requirements: + - type: "skill" + gid: "havencast" + level: 1 + - type: "stat" + gid: "mana" + value: 1 + results: + - type: "condition" + gid: "light" + duration: 3600 # 1 Hour + message: "A ball of light glows before you." + - type: "xp" + gid: "havencast" + base: 3 -- cgit v1.2.3