character.rb 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. def character_embed(character:, event:, section: nil, image: nil)
  2. # Find the author, if they're a member, or in DMs use the event's author
  3. member = if event.server
  4. if character.user_id.match(/public/i)
  5. 'Public'
  6. else
  7. event.server.member(character.user_id)
  8. end
  9. else
  10. event.author
  11. end
  12. fields = []
  13. embed = Embed.new(
  14. title: character.name,
  15. color: character.type_color
  16. )
  17. # Save image, if there is one, and footer info
  18. default_img = CharImage.where(char_id: character.id).find_by(keyword: 'Default')
  19. footer_info = [character.active, character.rating]
  20. embed.thumbnail = { url: default_img.url } if default_img
  21. # Fill out the fields based on the section
  22. case section
  23. when /all/i, /default/i, nil
  24. embed.description = character.personality if character.personality
  25. fields = char_type(character, fields)
  26. fields = char_status(character, fields)
  27. fields = char_bio(character, fields)
  28. fields = char_rumors(character, fields)
  29. fields = char_dm_notes(character, fields, event)
  30. when /bio/i
  31. embed.description = character.personality if character.personality
  32. fields = char_bio(character, fields)
  33. fields = char_dm_notes(character, fields, event)
  34. when /types?/i
  35. fields = char_type(character, fields)
  36. when /status/i
  37. fields = char_status(character, fields)
  38. when /rumors?/i
  39. fields = char_rumors(character, fields)
  40. when /images?/i
  41. image ||= default_img
  42. if image
  43. unless image.keyword == 'Default'
  44. embed.title =
  45. "#{character.name} | #{image.keyword}"
  46. end
  47. embed.image = { url: image.url }
  48. # Replace the rating with the image's rating
  49. footer_info.pop
  50. footer_info.push(image.category)
  51. else
  52. embed.description = 'No character images found!'
  53. end
  54. # Remove default image
  55. embed.thumbnail = nil
  56. when /bags?/i, /inventory/i
  57. fields = char_inv(character, fields)
  58. end
  59. # Add fields to embed
  60. embed.fields = fields
  61. # Add ID to footer, and apply to embed
  62. footer_info.push(character.id)
  63. author_footer(embed, member, footer_info)
  64. end
  65. def char_bio(char, fields)
  66. # Find the appropriate teams
  67. char_teams = CharTeam.where(char_id: char.id, active: true).map(&:team_id)
  68. teams = Team.where(id: char_teams).map(&:name)
  69. if char.hometown
  70. fields.push(
  71. { name: 'Hometown', value: char.hometown, inline: true }
  72. )
  73. end
  74. if char.location
  75. fields.push(
  76. { name: 'Location', value: char.location, inline: true }
  77. )
  78. end
  79. if char.likes
  80. fields.push(
  81. { name: 'Likes', value: char.likes }
  82. )
  83. end
  84. if char.dislikes
  85. fields.push(
  86. { name: 'Dislikes', value: char.dislikes }
  87. )
  88. end
  89. if char.backstory
  90. fields.push(
  91. { name: 'Backstory', value: char.backstory }
  92. )
  93. end
  94. if char.recent_events
  95. fields.push(
  96. { name: 'Recent Events', value: char.recent_events }
  97. )
  98. end
  99. if char.other
  100. fields.push(
  101. { name: 'Other', value: char.other }
  102. )
  103. end
  104. unless teams.empty?
  105. fields.push(
  106. { name: 'Team', value: teams.join("\n") }
  107. )
  108. end
  109. fields
  110. end
  111. def char_type(char, fields)
  112. sp = char.shiny ? "#{char.species} #{Emoji::STAR}" : char.species
  113. if char.species
  114. fields.push(
  115. { name: 'Species', value: sp, inline: true }
  116. )
  117. end
  118. if char.types
  119. fields.push(
  120. { name: 'Type', value: char.types, inline: true }
  121. )
  122. end
  123. if char.attacks
  124. attacks = char.attacks
  125. attacks = attacks.gsub(/\s?\|\s?/, "\n")
  126. fields.push({ name: 'Attacks', value: attacks })
  127. end
  128. fields
  129. end
  130. def char_rumors(char, fields)
  131. if char.warnings
  132. fields.push(
  133. { name: 'Warnings', value: char.warnings }
  134. )
  135. end
  136. if char.rumors
  137. rumors = char.rumors.split(/\s?\|\s?/)
  138. rumors = rumors.shuffle
  139. rumors = rumors.join("\n")
  140. fields.push({ name: 'Rumors', value: rumors })
  141. end
  142. fields
  143. end
  144. def char_status(char, fields, status_effects=nil)
  145. # Find any status effects on the character
  146. status_effects = CharStatus.where(char_id: char.id)
  147. if char.age
  148. fields.push(
  149. { name: 'Age', value: char.age, inline: true }
  150. )
  151. end
  152. if char.gender
  153. fields.push(
  154. { name: 'Gender', value: char.gender, inline: true }
  155. )
  156. end
  157. if char.weight
  158. fields.push(
  159. { name: 'Weight', value: char.weight, inline: true }
  160. )
  161. end
  162. if char.height
  163. fields.push(
  164. { name: 'Height', value: char.height, inline: true }
  165. )
  166. end
  167. if char.orientation
  168. fields.push(
  169. { name: 'Sexual Orientation', value: char.orientation, inline: true }
  170. )
  171. end
  172. if char.relationship
  173. fields.push(
  174. { name: 'Relationship Status', value: char.relationship, inline: true }
  175. )
  176. end
  177. afs = []
  178. status_effects.each do |se|
  179. s = Status.find(se.status_id)
  180. if s.amount
  181. afs.push("#{se.amount}% #{s.effect.downcase}")
  182. else
  183. afs.push(s.effect.capitalize)
  184. end
  185. end
  186. unless afs.empty?
  187. fields.push(
  188. { name: 'Current Afflictions', value: afs.join("\n") }
  189. )
  190. end
  191. fields
  192. end
  193. def char_inv(char, fields)
  194. # Retrive array of [item amount, item name], and format
  195. inv = char.fetch_inventory
  196. bags = inv.map { |i| i[0] > 1 ? "#{i[1]} [#{i[0]}]" : i[1] }
  197. # Show formatted items
  198. value = bags.empty? ? "#{char.name} doesn't have any items" : bags.join("\n")
  199. fields.push({ name: 'Bags', value: value })
  200. fields
  201. end
  202. def char_dm_notes(char, fields, event)
  203. return fields unless ENV['DM_CH'].include?(event.channel.id.to_s)
  204. if char.dm_notes
  205. fields.push(
  206. { name: 'DM Notes', value: char.dm_notes }
  207. )
  208. end
  209. fields
  210. end
  211. def char_list_embed(chars, group, sort = nil)
  212. fields = []
  213. list = {}
  214. case group
  215. when /active/i
  216. title = "Registered Guild Members -- [#{chars.count}]"
  217. desc = 'These are the pokemon registered to the guild, sorted by primary type'
  218. when /archived/i
  219. title = "Archived Guild Members -- [#{chars.count}]"
  220. desc = 'These are the pokemon in the guild archives, sorted by primary type'
  221. when /npc/i
  222. title = "Registered Guild NPCs -- [#{chars.length}]"
  223. desc = 'These are the NPCs from all around Zaplana, sorted by current location'
  224. when /special/i
  225. title = "Special Characters -- [#{chars.count}]"
  226. desc = 'These are the special pokemon around Zaplana, sorted by category'
  227. end
  228. case sort&.first
  229. when Type
  230. sort.each do |s|
  231. list[s.name] = chars.map do |c|
  232. next unless c.types.split('/').first === s.name
  233. name = c.name
  234. name = "|| #{name} ||" if c.rating&.match(/NSFW/i)
  235. name
  236. end.compact
  237. end
  238. list = list.reject { |_k, v| v == [] }
  239. list.each do |k, v|
  240. fields.push({ name: k, value: v.join(', ') })
  241. end
  242. when Region
  243. sort.each do |s|
  244. list[s.name] = chars.map do |c|
  245. next unless c.region == s.name
  246. name = c.name
  247. name = "*#{name}*" if c.user_id.match(/public/i)
  248. name = "|| #{name} ||" if c.rating&.match(/NSFW/i)
  249. name
  250. end.compact
  251. end
  252. list['Unknown'] = chars.map do |c|
  253. next unless c.region.nil?
  254. name = c.name
  255. name = "*#{name}*" if c.user_id.match(/public/i)
  256. name = "|| #{name} ||" if c.rating&.match(/NSFW/i)
  257. name
  258. end.compact
  259. list = list.reject { |_k, v| v == [] }
  260. list.each do |k, v|
  261. fields.push({ name: k, value: v.join(', ') })
  262. end
  263. when nil
  264. list['guild'] = []
  265. list['adoptable'] = []
  266. list['legend'] = []
  267. chars.each do |c|
  268. case c.special
  269. when /legend/i
  270. list['legend'].push("#{c.name}, #{c.species} -- last seen: #{c.location || '???'}")
  271. when /guild/i
  272. list['guild'].push("#{c.name}, #{c.species}")
  273. else
  274. list['adoptable'].push("#{c.name}, #{c.species} -- #{c.location || '???'}")
  275. end
  276. end
  277. list = list.reject { |_k, v| v == [] }
  278. list.each do |k, v|
  279. case k
  280. when /legend/i
  281. fields.push({ name: 'Mythic/Legend Pokemon', value: v.join("\n") })
  282. when /guild/i
  283. fields.push({ name: 'Guild Employees', value: v.join("\n") })
  284. when /adoptable/i
  285. fields.push({ name: 'Adoptable NPCs', value: v.join("\n") })
  286. end
  287. end
  288. end
  289. fields.push({ name: 'No Resulst', value: '--' }) if fields.empty?
  290. Embed.new(
  291. title: title,
  292. description: desc,
  293. fields: fields,
  294. footer: {
  295. text: 'React to Navigate | 1. Active | 2. Archived | 3. NPCs | 4. Special'
  296. }
  297. )
  298. end
  299. def user_char_embed(chars, member, nsfw=nil)
  300. fields = []
  301. active = []
  302. archived = []
  303. npcs = []
  304. user_name = member&.nickname || member&.name || 'Unknown User'
  305. chars.each do |char|
  306. case char.active
  307. when 'Active'
  308. active.push char
  309. when 'Archived'
  310. archived.push char.name
  311. when 'NPC'
  312. npcs.push char.name
  313. end
  314. end
  315. active.each.with_index do |char, i|
  316. name = if nsfw && char.rating == 'NSFW'
  317. "#{i + 1} || #{char.name} ||"
  318. else
  319. "#{i + 1} #{char.name}"
  320. end
  321. fields.push({
  322. name: name,
  323. value: "#{char.species} -- #{char.types}"
  324. })
  325. end
  326. unless archived.empty?
  327. fields.push({
  328. name: "#{user_name}'s Archived Characters",
  329. value: archived.join(', ')
  330. })
  331. end
  332. fields.push({ name: "#{user_name}'s NPCs", value: npcs.join(', ') }) unless npcs.empty?
  333. # Find allowed active characters
  334. allowed = member ? User.find(member.id.to_s).allowed_chars(member) : '???'
  335. embed = Embed.new(
  336. title: "#{user_name}'s Characters [#{active.count}/#{allowed}]",
  337. description: 'Click on the corresponding reaction to view the character',
  338. fields: fields
  339. )
  340. embed.color = member&.color&.combined if member&.color
  341. embed
  342. end
  343. def dup_char_embed(chars, name)
  344. fields = []
  345. chars.each.with_index do |char, i|
  346. fields.push({
  347. name: "#{Emoji::NUMBERS[i]}: #{char.species}",
  348. value: "Created by <@#{char.user_id}>"
  349. })
  350. end
  351. Embed.new(
  352. title: "Which #{name}?",
  353. description: 'Click on the corresponding reaction to pick',
  354. fields: fields
  355. )
  356. end
  357. def image_list_embed(character, event)
  358. # Find the author, if they're a member, or in DMs use the event's author
  359. member = if event.server
  360. if character.user_id.match(/public/i)
  361. 'Public'
  362. else
  363. event.server.member(character.user_id)
  364. end
  365. else
  366. event.author
  367. end
  368. # Grab an array of the character's images
  369. images = CharImage.where(char_id: character.id).
  370. map { |i| "[#{i.keyword}](#{i.url})" }
  371. # Create Embed
  372. embed = Embed.new(
  373. title: character.name,
  374. description: images.join("\n"),
  375. color: character.type_color
  376. )
  377. # Add footer to embed
  378. author_footer(embed, member, [character.active, character.id])
  379. end
  380. def nsfw_char_embed(character, event)
  381. # Find the author, if they're a member,
  382. member = event.server.member(character.user_id)
  383. # Create Embed
  384. embed = Embed.new(
  385. title: character.name,
  386. color: character.type_color,
  387. fields: [{
  388. name: 'Wrong Channel!',
  389. value: 'The requested information contains NSFW content'
  390. }]
  391. )
  392. embed.thumbnail = nil
  393. # Apply appropriate footer to embed
  394. author_footer(embed, member, [character.active, character.rating, character.id])
  395. end