character.rb 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  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, event, nsfw=nil)
  284. fields = []
  285. active = []
  286. archived = []
  287. npcs = []
  288. deleted = []
  289. user_name = member&.nickname || member&.name || "Unknown User"
  290. chars.each do |char|
  291. case char.active
  292. when 'Active'
  293. active.push char
  294. when 'Archived'
  295. archived.push char.name
  296. when 'NPC'
  297. npcs.push char.name
  298. when 'Deleted'
  299. deleted.push char.name
  300. end
  301. end
  302. active.each.with_index do |char, i|
  303. name = nsfw && char.rating == 'NSFW' ?
  304. "#{Emoji::NUMBERS[i]} || #{char.name} ||" : "#{Emoji::NUMBERS[i]} #{char.name}"
  305. fields.push({
  306. name: name,
  307. value: "#{char.species} -- #{char.types}"
  308. })
  309. end
  310. unless archived.empty?
  311. fields.push({
  312. name: "#{user_name}'s Archived Characters",
  313. value: archived.join(", ")
  314. })
  315. end
  316. unless npcs.empty?
  317. fields.push({ name: "#{user_name}'s NPCs", value: npcs.join(", ") })
  318. end
  319. unless deleted.empty? && !ENV['ADMIN_CH'].include?(event.channel.id.to_s)
  320. fields.push({ name: "#{user_name}'s Deleted Characters", value: deleted.join(", ") })
  321. end
  322. # Find allowed active characters
  323. allowed = member ? User.find(member.id.to_s).allowed_chars(member) : '???'
  324. embed = Embed.new(
  325. title: "#{user_name}'s Characters [#{active.count}/#{allowed}]",
  326. description: "Click on the corresponding reaction to view the character",
  327. fields: fields
  328. )
  329. embed.color = member&.color&.combined if member&.color
  330. embed
  331. end
  332. def dup_char_embed(chars, name)
  333. fields = []
  334. chars.each.with_index do |char, i|
  335. fields.push({
  336. name: "#{Emoji::NUMBERS[i]}: #{char.species}",
  337. value: "Created by <@#{char.user_id}>"
  338. })
  339. end
  340. Embed.new(
  341. title: "Which #{name}?",
  342. description: "Click on the corresponding reaction to pick",
  343. fields: fields
  344. )
  345. end
  346. def alt_form_embed(char, fields)
  347. # Find Base Character Form
  348. chars = []
  349. if char.alt_form
  350. chars.push( Character.find(char.alt_form) )
  351. else
  352. chars.push(char)
  353. end
  354. # Add forms
  355. chars.concat( Character.where(alt_form: chars.first.id) )
  356. # Display forms
  357. chars.each.with_index do |char, i|
  358. fields.push({
  359. name: "#{Emoji::NUMBERS[i]} #{char.name}",
  360. value: "#{char.species} -- #{char.types}"
  361. })
  362. end
  363. # return fields
  364. fields
  365. end
  366. def image_list_embed(character, event)
  367. # Find the author, if they're a member, or in DMs use the event's author
  368. if event.server
  369. member = character.user_id.match(/public/i) ? 'Public' :
  370. event.server.member(character.user_id)
  371. else
  372. member = event.author
  373. end
  374. # Grab an array of the character's images
  375. images = CharImage.where(char_id: character.id).
  376. map{ |i| "[#{i.keyword}](#{i.url})" }
  377. # Create Embed
  378. embed = Embed.new(
  379. title: character.name,
  380. description: images.join("\n"),
  381. color: character.type_color
  382. )
  383. # Add footer to embed
  384. author_footer(embed, member, [character.active, character.id])
  385. end
  386. def nsfw_char_embed(character, event)
  387. # Find the author, if they're a member,
  388. member = event.server.member(character.user_id)
  389. # Create Embed
  390. embed = Embed.new(
  391. title: character.name,
  392. color: character.type_color,
  393. fields: [{
  394. name: 'Wrong Channel!',
  395. value: 'The requested information contains NSFW content'
  396. }]
  397. )
  398. embed.thumbnail = nil
  399. # Apply appropriate footer to embed
  400. author_footer(embed, member, [character.active, character.rating, character.id])
  401. end