character.rb 12 KB

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