Ver código fonte

Merge branch 'master' of code.ajsw.is:PMD/rotom_bot

* 'master' of code.ajsw.is:PMD/rotom_bot:
  finishing touches
  remove virtual studios settings
  add gems
  pray it all works
  level up
  weather and stats start
Kylie Jo Swistak 6 anos atrás
pai
commit
1987d37730
51 arquivos alterados com 431 adições e 99 exclusões
  1. 1 0
      .gitignore
  2. 1 0
      Gemfile
  3. BIN
      OpenSans-SemiBold.ttf
  4. 17 9
      app/controllers/status_controller.rb
  5. 99 0
      app/controllers/users.rb
  6. 18 39
      app/models/image_merger.rb
  7. 7 5
      app/models/users.rb
  8. 5 1
      app/responses/character.rb
  9. 1 1
      app/responses/poll.rb
  10. 34 0
      app/responses/status.rb
  11. 2 2
      app/responses/team.rb
  12. 168 35
      bot.rb
  13. 78 7
      db/schema.sql
  14. BIN
      images/BG.png
  15. BIN
      images/Castform.png
  16. BIN
      images/CastformRain.png
  17. BIN
      images/CastformSnow.png
  18. BIN
      images/CastformSun.png
  19. BIN
      images/Day_Cloudy.png
  20. BIN
      images/Day_Fair.png
  21. BIN
      images/Day_Fire.png
  22. BIN
      images/Day_Ice.png
  23. BIN
      images/Day_More_Cloudy.png
  24. BIN
      images/Day_Mostly_Cloudy.png
  25. BIN
      images/Day_Night.png
  26. BIN
      images/Day_Night_Showers.png
  27. BIN
      images/Day_Partly_Cloudy.png
  28. BIN
      images/Day_Rainy.png
  29. BIN
      images/Day_Rainy_Sun.png
  30. BIN
      images/Day_Sandstorm.png
  31. BIN
      images/Day_Snow.png
  32. BIN
      images/Day_Snow_Mix.png
  33. BIN
      images/Day_Snow_Sun.png
  34. BIN
      images/Day_Stormy.png
  35. BIN
      images/Day_Stormy_Sun.png
  36. BIN
      images/Day_Sunny.png
  37. BIN
      images/Day_Windy.png
  38. BIN
      images/FrameFG.png
  39. BIN
      images/Image_Builder/LevelUp.png
  40. BIN
      images/Image_Builder/LevelUp0.png
  41. BIN
      images/Image_Builder/LevelUp1.png
  42. BIN
      images/Image_Builder/LevelUp2.png
  43. BIN
      images/Image_Builder/Weather.png
  44. BIN
      images/Image_Builder/user_url.png
  45. BIN
      images/Image_Builder/user_url_img.png
  46. BIN
      images/LevelUp.png
  47. BIN
      images/LevelUpFont.png
  48. BIN
      images/TheMap.png
  49. BIN
      images/TheMap1.png
  50. BIN
      images/TheMap2.png
  51. BIN
      images/TheMap3.png

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 .env
 Gemfile.lock
 .DS_Store
+.vs/*

+ 1 - 0
Gemfile

@@ -10,6 +10,7 @@ gem 'discordrb', '~> 3.3.0'
 gem 'pg'
 gem 'terminal-table'
 gem 'rmagick'
+gem 'down'
 
 group :development do
   gem 'dotenv'

BIN
OpenSans-SemiBold.ttf


+ 17 - 9
app/controllers/status_controller.rb

@@ -1,32 +1,40 @@
 class StatusController
-  def self.edit_status(name, effect)
+  def self.edit_status(name, effect, flag=nil)
     if status = Status.find_by(name: name)
-      status.update!(effect: effect)
+      status.update!(effect: effect, amount: flag)
       status.reload
     else
-      status = Status.create(name: name, effect: effect)
+      flag = flag ? flag : true
+      status = Status.create(name: name, effect: effect, amount: flag)
     end
 
     status
   end
 
-  def self.edit_char_status(status, amount, char)
+  def self.edit_char_status(char, status, amount=nil)
     char_st = CharStatus.where(char_id: char.id).find_by(status_id: status.id)
-    amt = amount.to_i
+    amt = amount.to_i if amount
 
-    if char_st && amt
+    if char_st && amt && status.amount
       char_st.update(amount: char_st.amount + amt)
       char_st.reload
 
       char_st
-    elsif amt
+    elsif char_st && !status.amount
+      error_embed("The user is already afflicted with #{status.name}")
+    elsif amount && !amt && status.amount
+      error_embed("Amount must be numerical!")
+    elsif amt && status.amount
       CharStatus.create(
         char_id: char.id,
         status_id: status.id,
         amount: amt
       )
-    else
-      error_embed("Amount must be numerical!")
+    elsif !status.amount
+      CharStatus.create(
+        char_id: char.id,
+        status_id: status.id,
+      )
     end
   end
 end

+ 99 - 0
app/controllers/users.rb

@@ -0,0 +1,99 @@
+class UsersController
+  def self.stat_image(user, member, stats=nil)
+    size_width = 570;
+    size_height = 376;
+    stats_frame =  "../../images/LevelUp.png"
+    level_up = "../../images/LevelUpFont.png"
+    user_url_img = "../../images/Image_Builder/user_url_img.png"
+    output_file =  "../../images/Image_Builder/LevelUp"
+
+    Down.download(member.avatar_url, destination: user_url_img)
+
+    #Gif Destroyer
+    i = Magick::ImageList.new(user_url_img)
+    i[0].write(user_url_img) if i.count > 1
+
+    if stats
+      merge_image(
+        [stats_frame, level_up, user_url_img],
+        output_file,
+        size_width,
+        size_height,
+        [nil, nil, 19],
+        [nil, nil, 92],
+        [size_width, size_width, 165],
+        [size_height, size_height, 165]
+      )
+    else
+      merge_image(
+        [stats_frame, user_url_img],
+        output_file,
+        size_width,
+        size_height,
+        [nil, 19],
+        [nil, 92],
+        [size_width, 165],
+        [size_height, 165]
+      )
+    end
+
+    ratio = 0.5
+    user_name = member.nickname || member.name
+    short_name = user_name.length > 25 ? "#{user_name[0..22]}..." : user_name
+    rank = User.order(unboosted_xp: :desc)
+    user_rank = rank.detect{ |r| r.id == user.id }
+
+    gc = Draw.new
+
+    gc.font('../../OpenSans-SemiBold.ttf')
+
+    gc.stroke('#39c4ff').fill('#39c4ff')
+    gc.rectangle(42, 48, 42 + (95 * ratio), 48 + 3)
+
+    gc.stroke('none').fill('black')
+    gc.pointsize('15')
+    gc.text(15,25, short_name)
+    gc.text(40, 45, user.level.to_s)
+    gc.text(15, 290, user_rank.to_s)
+    gc.text(40, 65, user.boosted_xp.to_s)
+
+    gc.stroke('white').fill('white')
+    gc.pointsize('30')
+    gc.text(40,330, user_name)
+    reached = "reached level #{user.level}!"
+    gc.text(40,360, reached)
+
+    if stats
+      gc.stroke('none').fill('black')
+      gc.pointsize('18')
+      gc.text(450, 97, stats['hp'].to_s)
+      gc.text(450, 127, stats['attack'].to_s)
+      gc.text(450, 159, stats['defense'].to_s)
+      gc.text(450, 191, stats['sp_attack'].to_s)
+      gc.text(450, 222, stats['sp_defense'].to_s)
+      gc.text(450, 255, stats['speed'].to_s)
+
+      gc.stroke('none').fill('maroon')
+      gc.text(505, 97, user.hp - stats['hp'].to_s)
+      gc.text(505, 127, user.attack - stats['attack'].to_s)
+      gc.text(505, 159, user.defense - stats['defense'].to_s)
+      gc.text(505, 191, user.sp_attack - stats['sp_attack'].to_s)
+      gc.text(505, 222, user.sp_defense - stats['sp_defense'].to_s)
+      gc.text(505, 255, user.speed - stats['speed'].to_s)
+    else
+      gc.stroke('none').fill('black')
+      gc.pointsize('18')
+      gc.text(450, 97, user.hp.to_s)
+      gc.text(450, 127, user.attack.to_s)
+      gc.text(450, 159, user.defense.to_s)
+      gc.text(450, 191, user.sp_attack.to_s)
+      gc.text(450, 222, user.sp_defense.to_s)
+      gc.text(450, 255, user.speed.to_s)
+    end
+
+    u = Magick::ImageList.new("#{output_file}.png")
+    gc.draw(u[0])
+
+    u.write("#{output_file}.png")
+  end
+end

+ 18 - 39
app/models/image_merger.rb

@@ -2,56 +2,35 @@ require 'rmagick'
 include Magick
 
 def append_image(image1_in, images2_in, image_out)
-  i = Magick::ImageList.new
   i = Magick::ImageList.new(image1_in,images2_in)
 
   u = i.append(true);
   u.write('images/Type Double.png');
 end
 
-def crop_image()
-  images = ['images/Type Bug.png', 'images/Type Dark.png', 'images/Type Dark - Copy.png']
+def merge_image(image_array, image_out, output_width, output_height, xaxis, yaxis, image_width, image_height)
+  i = Magick::ImageList.new(*image_array)
 
-  img = Magick::Image.read(images[0]).first # path of Orignal image that has to be worked upon
-  puts img.inspect
+  v = Magick::ImageList.new
+  arr = Array.new(0)
 
-  def try(x,y,width,height)
-    images = ['images/Type Bug.png', 'images/Type Dark.png', 'images/Type Dark - Copy.png']
+  i.each.with_index do |item, index|
+    if image_width[index] && image_height[index]
+      i[index] = item.resize(image_width[index], image_height[index])
+    end
 
-    # converting x,y , width and height to integer values in next four statements
-    x= x.to_i
-    y= y.to_i
-    width= width.to_i
-    height= height.to_i
+    if xaxis[index] && yaxis[index]
+      v.new_image(output_width, output_height) { self.background_color = "transparent" }
 
-    # Demonstrate the Image#crop method
-    @st = images[0] # path of image written after changing size or not changing also
-    img = Magick::Image.read(@st)[0]
+      i[index] = v.composite(i[index], xaxis[index], yaxis[index], OverCompositeOp).write(image_out + index.to_s + ".png");  
+    else
+      i[index].write(image_out + index.to_s + ".png");  
+    end
 
-    # Crop the specified rectangle out of the img.
-    chopped = img.crop(x, y, width,height)
-
-    # Go back to the original and highlight the area
-    # corresponding to the retained rectangle.
-    rect = Magick::Draw.new
-    rect.stroke('transparent')
-    rect.fill('black')
-    rect.fill_opacity(1.0)
-    rect.rectangle(x, y, 100+x, 10+y)
-    rect.draw(img)
-
-    img.write(images[1]) #path of image written before cropping
-
-    # Create a image to use as a background for
-    # the “after” image.
-    bg = Magick::Image.new(img.columns, img.rows)
-
-    # Composite the the “after” (chopped) image on the background
-    bg = bg.composite(chopped, 38,81, Magick::OverCompositeOp)
-
-    bg.write(images[2]) # path of image written after cropping the desired part
-    exit
+    arr << image_out + index.to_s + ".png"
   end
 
-  try(100, 50, 150, 100)
+  i = Magick::ImageList.new(*arr)
+  i = i.flatten_images();
+  i.write(image_out + ".png")
 end

+ 7 - 5
app/models/users.rb

@@ -32,7 +32,7 @@ class User < ActiveRecord::Base
     self
   end
 
-  def update_xp(msg)
+  def update_xp(msg, user=nil)
     xp =
       case msg.length
       when 0..40 then 0
@@ -49,12 +49,12 @@ class User < ActiveRecord::Base
     )
 
     self.reload
-    level_up if next_level && boosted_xp > next_level
+    reply = level_up(user) if next_level && boosted_xp > next_level
 
-    self
+    reply
   end
 
-  def level_up
+  def level_up(user=nil)
     if level < 100
       next_level = (level + 6) ** 3 / 10.0
       self.update(level: level + 1, next_level: next_level.round)
@@ -65,10 +65,12 @@ class User < ActiveRecord::Base
     n = Nature.find(nature)
 
     stats = stat_calc(n.up_stat, n.down_stat)
+    img = stat_image(self, user, stats) if user
+
     self.update(stats)
     self.reload
 
-    self
+    img
   end
 
   def stat_calc(up_stat, down_stat)

+ 5 - 1
app/responses/character.rb

@@ -149,7 +149,11 @@ def char_status(char, fields, status_effects=nil)
   afs = []
   status_effects.each do |se|
     s = Status.find(se.status_id)
-    afs.push("#{se.amount}% #{s.effect.downcase}")
+    if s.amount
+      afs.push("#{se.amount}% #{s.effect.downcase}")
+    else
+      afs.push(s.effect.capitalize)
+    end
   end
 
   fields.push(

+ 1 - 1
app/responses/poll.rb

@@ -5,7 +5,7 @@ def new_poll_embed(event, question, options)
   options.map.with_index do |option, index|
     fields.push({
       name: "#{Emoji::LETTERS[index]} #{option}",
-      value: CharAppResponses::INLINE_SPACE, inline: true
+      value: CharApp::INLINE_SPACE, inline: true
     })
   end
 

+ 34 - 0
app/responses/status.rb

@@ -0,0 +1,34 @@
+def status_list
+  statuses = Status.all
+  amounts = []
+  no_amounts = []
+
+  statuses.each do |s|
+    if s.amount
+      amounts.push(s.name)
+    else
+      no_amounts.push(s.name)
+    end
+  end
+
+  fields = []
+  fields.push(
+    { name: 'Stackable Effects', value: amounts.join(", ")}
+  )unless amounts.empty?
+
+  fields.push(
+    { name: 'Non-Stackable Effects', value: no_amounts.join(", ")}
+  )unless no_amounts.empty?
+
+  Embed.new(
+    title: 'Statuses',
+    fields: fields
+  )
+end
+
+def status_details(status)
+  Embed.new(
+    title: status.name,
+    description: "#{status.effect.capitalize}\n(Stacks: #{status.amount})"
+  )
+end

+ 2 - 2
app/responses/team.rb

@@ -34,12 +34,12 @@ def team_embed(team)
 
   fields.push({
     name: 'Active Members',
-    value: active.join(",")
+    value: active.join(", ")
   })unless active.empty?
 
   fields.push({
     name: 'Inactive Members',
-    value: inactive.join(",")
+    value: inactive.join(", ")
   })unless inactive.empty?
 
   embed = Embed.new(

+ 168 - 35
bot.rb

@@ -4,6 +4,7 @@ require 'yaml'
 require 'json'
 require 'terminal-table'
 require 'rmagick'
+require 'down'
 
 BOT_ENV = ENV.fetch('BOT_ENV') { 'development' }
 Bundler.require(:default, BOT_ENV)
@@ -42,6 +43,107 @@ Dir['./lib/*.rb'].each { |f| require f }
 token = ENV['DISCORD_BOT_TOKEN']
 bot = Discordrb::Bot.new(token: token)
 
+# Methods
+
+def stat_image(user, member, stats=nil)
+  size_width = 570;
+  size_height = 376;
+  stats_frame =  "images/LevelUp.png"
+  level_up = "images/LevelUpFont.png"
+  user_url_img = "images/Image_Builder/user_url_img.png"
+  output_file =  "images/Image_Builder/LevelUp"
+
+  Down.download(member.avatar_url, destination: user_url_img)
+
+  #Gif Destroyer
+  i = Magick::ImageList.new(user_url_img)
+  i[0].write(user_url_img) if i.count > 1
+
+  if stats
+    merge_image(
+      [stats_frame, level_up, user_url_img],
+      output_file,
+      size_width,
+      size_height,
+      [nil, nil, 19],
+      [nil, nil, 92],
+      [size_width, size_width, 165],
+      [size_height, size_height, 165]
+    )
+  else
+    merge_image(
+      [stats_frame, user_url_img],
+      output_file,
+      size_width,
+      size_height,
+      [nil, 19],
+      [nil, 92],
+      [size_width, 165],
+      [size_height, 165]
+    )
+  end
+
+  ratio = 0.5
+  user_name = member.nickname || member.name
+  short_name = user_name.length > 25 ? "#{user_name[0..22]}..." : user_name
+  rank = User.order(unboosted_xp: :desc)
+  user_rank = rank.index{ |r| r.id == user.id } + 1
+
+  gc = Draw.new
+
+  gc.font('OpenSans-SemiBold.ttf')
+
+  gc.stroke('#39c4ff').fill('#39c4ff')
+  gc.rectangle(42, 48, 42 + (95 * ratio), 48 + 3)
+
+  gc.stroke('none').fill('black')
+  gc.pointsize('15')
+  gc.text(15,25, short_name)
+  gc.text(40, 45, "Lv.#{user.level}")
+  gc.text(15, 290, "Rank: #{user_rank}")
+  gc.text(40, 65, "Exp: #{user.boosted_xp}")
+
+  gc.stroke('white').fill('white')
+  gc.pointsize('30')
+  gc.text(40,330, user_name)
+  gc.text(40,360, "reached level #{user.level}!")
+
+  if stats
+    gc.stroke('none').fill('black')
+    gc.pointsize('18')
+    gc.text(450, 97, stats['hp'].to_s)
+    gc.text(450, 127, stats['attack'].to_s)
+    gc.text(450, 159, stats['defense'].to_s)
+    gc.text(450, 191, stats['sp_attack'].to_s)
+    gc.text(450, 222, stats['sp_defense'].to_s)
+    gc.text(450, 255, stats['speed'].to_s)
+
+    gc.stroke('none').fill('maroon')
+    gc.text(505, 97, "+ #{stats['hp'] - user.hp}")
+    gc.text(505, 127, "+ #{stats['attack']- user.attack}")
+    gc.text(505, 159, "+ #{stats['defense'] - user.defense}")
+    gc.text(505, 191, "+ #{stats['sp_attack'] - user.sp_attack}")
+    gc.text(505, 222, "+ #{stats['sp_defense']- user.sp_defense}")
+    gc.text(505, 255, "+ #{stats['speed'] - user.speed}")
+  else
+    gc.stroke('none').fill('black')
+    gc.pointsize('18')
+    gc.text(450, 97, user.hp.to_s)
+    gc.text(450, 127, user.attack.to_s)
+    gc.text(450, 159, user.defense.to_s)
+    gc.text(450, 191, user.sp_attack.to_s)
+    gc.text(450, 222, user.sp_defense.to_s)
+    gc.text(450, 255, user.speed.to_s)
+  end
+
+  u = Magick::ImageList.new("#{output_file}.png")
+  gc.draw(u[0])
+
+  u.write("#{output_file}.png")
+  "#{output_file}.png"
+end
+
+#--
 
 # Commands: structure basic bot commands here
 commands = []
@@ -124,6 +226,34 @@ matchup = Command.new(:matchup, desc, opts) do |event, primary, secondary|
   end
 end
 
+opts = {
+  "@user" => "List all user stats",
+}
+desc = "Shows ones stats, level, rank, and experience"
+stats = Command.new(:stats, desc, opts) do |event, name|
+
+  case name
+  when UID
+    user_id = UID.match(name)
+    user = event.server.member(user_id[1])
+  when String
+    #See if you can find the name some other way?
+  end
+
+  channel = event.channel.id
+
+  # C# code for getting the percantage to the next level
+    #int levelprior = LevelUp[task].NextLevel - (10 * (LevelUp[task].CurrentLevel - 1) ^ 2);
+    #double ratio = (double)(LevelUp[task].Messages - levelprior) / (double)(LevelUp[task].NextLevel - levelprior);
+
+  usr = User.find_by!(id: user&.id)
+
+  output_file = stat_image(usr, user)
+  bot.send_file(channel, File.open(output_file, 'r'))
+rescue ActiveRecord::RecordNotFound => e
+  error_embed(e.message)
+end
+
 opts = {
   "" => "starts a new app",
   "name" => "edits an existing app",
@@ -423,11 +553,12 @@ member = Command.new(:member, desc, opts) do |event, name, section, keyword|
     end
   end
 
-
 rescue ActiveRecord::RecordNotFound => e
   error_embed("Record Not Found!", e.message)
 end
 
+desc = "Learn about Items"
+opts = { "" => "list all items", "item_name" => "show known info for the item" }
 item = Command.new(:item, desc, opts) do |event, name|
   i = name ? Item.find_by!(name: name.capitalize) : Item.all
 
@@ -444,7 +575,7 @@ rescue ActiveRecord::RecordNotFound
 end
 
 desc = "Add and remove items from characters' inventories"
-opts = { "item | (-/+) amount | character" => "" }
+opts = { "item | (-/+) amount | character" => "negative numbers remove items" }
 inv = Command.new(:inv, desc, opts) do |event, item, amount, name|
   char = Character.find_by!(name: name) if name
   itm = Item.find_by!(name: item) if item
@@ -472,23 +603,33 @@ rescue ActiveRecord::RecordNotFound => e
 end
 
 desc = "Update or edit statuses"
-opts = { "name | effect" => "" }
-status = Command.new(:status, desc, opts) do |event, name, effect|
-  if name && effect
-    s = StatusController.edit_status(name, effect)
+opts = { "name | effect" => "effect displays on user when afflicted" }
+status = Command.new(:status, desc, opts) do |event, name, effect, flag|
+  admin = event.user.roles.map(&:name).include?('Guild Masters')
+
+  if name && effect && admin
+    s = StatusController.edit_status(name, effect, flag)
 
     case s
     when Status
-      success_embed("Created Status: #{name}")
+      status_details(s)
     when Embed
       s
     end
+  elsif name && !effect
+    status_details(Status.find_by!(name: name))
+  elsif !name && !effect
+    status_list
+  elsif !admin
+    error_embed("You do not have permission to do that!")
   else
     command_error_embed("Could not create status!", status)
   end
+rescue ActiveRecord::RecordNotFound => e
+  error_embed(e.message)
 end
 
-opts = { "character | ailment | %afflicted" => "" }
+opts = { "character | ailment | %afflicted" => "afflictions apply in percentages" }
 afflict = Command.new(:afflict, desc, opts) do |event, name, status, amount|
   char = Character.find_by!(name: name) if name
   st = Status.find_by!(name: status) if status
@@ -496,12 +637,12 @@ afflict = Command.new(:afflict, desc, opts) do |event, name, status, amount|
   user = char.user_id.match(/public/i) ?
     'Public' : event.server.member(char.user_id)
 
-  if st && amount && char
+  if st && char
     user = char.user_id.match(/public/i) ?
       'Public' : event.server.member(char.user_id)
     color = CharacterController.type_color(char)
 
-    s = StatusController.edit_char_status(st, amount, char)
+    s = StatusController.edit_char_status(char, st, amount)
 
     case s
     when CharStatus
@@ -510,7 +651,7 @@ afflict = Command.new(:afflict, desc, opts) do |event, name, status, amount|
       s
     end
   else
-    command_error_embed("Error afflicting #{char}", afflict)
+    command_error_embed("Error afflicting #{char.name}", afflict)
   end
 rescue ActiveRecord::RecordNotFound => e
   error_embed(e.message)
@@ -635,12 +776,13 @@ commands = [
   poll,
   raffle,
   member,
-  item,
-  inv,
+  #item,
+  #inv,
   status,
   afflict,
   cure,
-  team
+  team,
+  stats
 ]
 
 #locked_commands = [inv]
@@ -674,27 +816,14 @@ bot.message do |event|
     else
       approval_react(event)
     end
-  #elsif content == 'test'
-    #User.import_user(File.open('users.txt', 'r'))
-  elsif content == 'pry'
-    binding.pry
-  elsif content == 'show me dem illegals'
-    users = User.all
-    illegals = []
-
-    users.each do |u|
-      allowed = u.level / 10 + 1
-      active = Character.where(user_id: u.id, active: 'Active').count
-      illegals.push("<@#{u.id}>, Level #{u.level}: #{active}/#{allowed}") if active > allowed
-    end
-    embed = error_embed("Members with too many pokemon", illegals.join("\n"))
-    event.send_embed("", embed)
+  elsif content == 'import users' && author == 215240568245190656
+    User.import_user(File.open('users.txt', 'r'))
   elsif !event.author.current_bot?
     usr = User.find_by(id: author.to_s)
     msg = URL.match(content) ? content.gsub(URL, "x" * 149) : content
 
-    usr = usr.update_xp(msg)
-    event.respond(usr) if usr.is_a? String
+    img = usr.update_xp(msg, event.author)
+    bot.send_file(event.message.channel, File.open(img, 'r')) if img
   end
 end
 
@@ -762,8 +891,8 @@ bot.reaction_add do |event|
 
   vote =
     case
-    when reactions[Emoji::Y]&.count.to_i > maj.round then :yes
-    when reactions[Emoji::N]&.count.to_i > maj.round then :no
+    when reactions[Emoji::Y]&.count.to_i > maj then :yes
+    when reactions[Emoji::N]&.count.to_i > maj then :no
     when reactions[Emoji::CHECK]&.count.to_i > 1 then :check
     when reactions[Emoji::CROSS]&.count.to_i > 1 then :cross
     when reactions[Emoji::CRAYON]&.count.to_i > 1 then :crayon
@@ -788,12 +917,16 @@ bot.reaction_add do |event|
     uid = UID.match(app.description)
     user =
       app.description.match(/public/i) ? 'Public' : event.server.member(uid[1])
+    img_url = case
+              when !app.thumbnail&.url.nil? then app.thumbnail.url
+              when !app.image&.url.nil? then app.image.url
+              end
 
     char = CharacterController.edit_character(app)
     img = ImageController.default_image(
-      app.thumbnail.url,
+      img_url,
       char.id
-    )if app.thumbnail
+    )if img_url
     color = CharacterController.type_color(char)
 
     embed = character_embed(

Diferenças do arquivo suprimidas por serem muito extensas
+ 78 - 7
db/schema.sql


BIN
images/BG.png


BIN
images/Castform.png


BIN
images/CastformRain.png


BIN
images/CastformSnow.png


BIN
images/CastformSun.png


BIN
images/Day_Cloudy.png


BIN
images/Day_Fair.png


BIN
images/Day_Fire.png


BIN
images/Day_Ice.png


BIN
images/Day_More_Cloudy.png


BIN
images/Day_Mostly_Cloudy.png


BIN
images/Day_Night.png


BIN
images/Day_Night_Showers.png


BIN
images/Day_Partly_Cloudy.png


BIN
images/Day_Rainy.png


BIN
images/Day_Rainy_Sun.png


BIN
images/Day_Sandstorm.png


BIN
images/Day_Snow.png


BIN
images/Day_Snow_Mix.png


BIN
images/Day_Snow_Sun.png


BIN
images/Day_Stormy.png


BIN
images/Day_Stormy_Sun.png


BIN
images/Day_Sunny.png


BIN
images/Day_Windy.png


BIN
images/FrameFG.png


BIN
images/Image_Builder/LevelUp.png


BIN
images/Image_Builder/LevelUp0.png


BIN
images/Image_Builder/LevelUp1.png


BIN
images/Image_Builder/LevelUp2.png


BIN
images/Image_Builder/Weather.png


BIN
images/Image_Builder/user_url.png


BIN
images/Image_Builder/user_url_img.png


BIN
images/LevelUp.png


BIN
images/LevelUpFont.png


BIN
images/TheMap.png


BIN
images/TheMap1.png


BIN
images/TheMap2.png


BIN
images/TheMap3.png


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff