LeonMMS

VXA-OS Email System - Client

Jan 21st, 2025
6
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 16.14 KB | None | 0 0
  1. # LM² - Email
  2. # v1.0
  3.  
  4. # configurações gerais
  5. module Vocab
  6.   EmailList = "Lista de Emails"
  7.   WriteEmail = "Escrever Email"
  8.   Send = "Enviar"
  9.   Body = "Corpo do Email"
  10.   MailName = "Nome do Email"
  11.   ReceiverName = "Nome do Jogador"
  12.   Claim = "Resgatar"
  13.   Email = "Emails"
  14.   Sender = "De:"
  15.   SendDate = "Data:"
  16.   ExpireDate = "Expira:"
  17.   AddItem = "Add Item"
  18. end
  19. module Configs
  20.   UNREAD_MAIL = 235
  21.   READ_MAIL = 236
  22.   WRITE_MAIL = 286
  23.   COLLECTED_MAIL = 539
  24.   EMAIL_ICON = 234
  25.   EMAIL_KEY = :LETTER_E
  26.   EMAILDATE = "%H:%M %d/%m/%y"
  27. end
  28.  
  29. # struct do email
  30. Email = Struct.new(:sender_name, :name, :body, :gold,
  31. :items, :state, :send_date, :expire_date)
  32. ItemMail = Struct.new(:type, :id, :amount)
  33.  
  34. #recebimento de pacotes do servidor
  35. module Handle_Data
  36.   def handle_player_email(buffer)
  37.     sender_name = buffer.read_string
  38.     name = buffer.read_string
  39.     body = buffer.read_string
  40.     state = buffer.read_byte
  41.     gold = buffer.read_int
  42.     size = buffer.read_byte
  43.     items = []
  44.     size.times {
  45.       items << ItemMail.new(
  46.         buffer.read_byte,
  47.         buffer.read_short,
  48.         buffer.read_short
  49.       )
  50.     }
  51.     send_date = Time.now - buffer.read_long
  52.     expire_date = Time.now + buffer.read_long
  53.     email = Email.new(sender_name, name, body, gold,
  54.                      items, state, send_date, expire_date)
  55.     $game_player.emails << email
  56.     $windows[:email_list].refresh if $windows[:email_list] && $windows[:email_list].visible
  57.     #$windows[:email_list]&.visible ruby 2.3 >
  58.   end
  59.  
  60.   def handle_email_delete(buffer)
  61.     mail_id = buffer.read_short
  62.     $game_player.emails.delete_at(mail_id)
  63.     $windows[:email_list].refresh if $windows[:email_list] && $windows[:email_list].visible
  64.   end
  65.  
  66. end
  67.  
  68. # envio de pacotes para o servidor
  69. module Send_Data
  70.   def send_player_email(mail_id, delete)
  71.     return unless @socket
  72.     buffer = Buffer_Writer.new
  73.     buffer.write_byte(Enums::Packet::EMAIL)
  74.     buffer.write_short(mail_id)
  75.     buffer.write_boolean(delete)
  76.     @socket.send(buffer.to_s)
  77.   end
  78.  
  79.   def send_player_write_email(receiver, name, body, gold, items, admin = false)
  80.     return unless @socket
  81.     buffer = Buffer_Writer.new
  82.     buffer.write_byte(Enums::Packet::EMAIL_WRITE)
  83.     buffer.write_boolean(admin)
  84.     buffer.write_string(receiver)
  85.     buffer.write_string(name)
  86.     buffer.write_string(body)
  87.     buffer.write_int(gold)
  88.     buffer.write_byte(items.size)
  89.     items.each{|item|
  90.       buffer.write_byte(item.type)
  91.       buffer.write_short(item.id)
  92.       buffer.write_short(item.amount)
  93.     }
  94.     @socket.send(buffer.to_s)
  95.   end  
  96. end
  97. # janela de lista de emails
  98. class Window_EmailList < Window_Selectable
  99.  
  100.   def initialize
  101.     super(173, 170, 236, 212)
  102.     self.visible = false
  103.     self.closable = true
  104.     self.title = Vocab::EmailList
  105.     Icon.new(self, width - 46, height - 36, Configs::WRITE_MAIL, Vocab::WriteEmail) { write_email}
  106.   end
  107.  
  108.   def line_height
  109.     22
  110.   end
  111.  
  112.   def make_list
  113.     @data = $game_player.emails
  114.   end
  115.  
  116.   def draw_item(index)
  117.     rect = item_rect_for_text(index)
  118.     icon_index = @data[index].state == 1 ? Configs::READ_MAIL : Configs::UNREAD_MAIL
  119.     rect2 = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
  120.     bitmap = Cache.system('Iconset')
  121.     contents.blt(3, rect.y, bitmap, rect2)
  122.     rect.x += 27
  123.     draw_text(rect, @data[index].name)
  124.   end
  125.  
  126.   def refresh
  127.     super
  128.   end
  129.  
  130.   def update
  131.     super
  132.     if Mouse.click?(:L) && index >= 0
  133.       $windows[:email_info].show(@data[index], index)
  134.       $windows[:email_write].hide
  135.       Sound.play_ok
  136.     end
  137.   end
  138.  
  139.   def write_email
  140.     $windows[:email_write].show
  141.     $windows[:email_info].hide
  142.     $windows[:equip].show
  143.   end
  144.  
  145. end
  146.  
  147. # janela de leitura de email
  148. class Window_EmailInfo < Window_Base
  149.  
  150.   def initialize
  151.     super(adjust_x, 151, 246, 300)
  152.     self.visible = false
  153.     self.closable = true
  154.     self.title = "Teste"
  155.     @claim_button = Button.new(self, 12 , height - 34, Vocab::Claim, 80) { claim }
  156.     @delete_button = Button.new(self, width - 92 , height - 34, Vocab::Delete, 80) { delete }
  157.     create_desc
  158.     @email = nil
  159.   end
  160.  
  161.   def line_height
  162.     20
  163.   end
  164.    
  165.   def adjust_x
  166.     $windows[:email_list].x + $windows[:email_list].width + 2
  167.   end  
  168.  
  169.  
  170.   def claim
  171.     $network.send_player_email(@id, false)
  172.     $game_player.emails[@id].state = 1
  173.     $windows[:email_list].refresh
  174.     refresh
  175.   end
  176.  
  177.   def delete
  178.     $network.send_player_email(@id, true)
  179.     $game_player.emails.delete_at(@id)
  180.     $windows[:email_list].refresh
  181.     hide
  182.   end
  183.  
  184.   def show(email, id)
  185.     @email = email
  186.     @id = id
  187.     self.title = @email.name
  188.     super()
  189.   end
  190.  
  191.   def refresh
  192.     contents.clear
  193.     return unless @email
  194.     @claim_button.enable = @email.state == 0
  195.     @delete_button.enable = @email.state == 1
  196.     contents.font.size = 16
  197.     change_color(system_color)
  198.     draw_text(0, -2, contents_width, line_height, "#{Vocab::Name}:", 0)
  199.     draw_text(0, 20, contents_width, line_height, Vocab::Sender, 0)
  200.     draw_text(0, 42, contents_width, line_height, Vocab::SendDate, 0)
  201.     draw_text(0, 64, contents_width, line_height, Vocab::ExpireDate, 0)
  202.     change_color(normal_color)
  203.     x = text_size("#{Vocab::Name}:").width + 8
  204.     draw_text(x, -2, contents_width, line_height, @email.name, 0)
  205.     x = text_size(Vocab::Sender).width + 8
  206.     draw_text(x, 20, contents_width, line_height, @email.sender_name, 0)
  207.     x = text_size(Vocab::SendDate).width + 8
  208.     time = @email.send_date.strftime(Configs::EMAILDATE)
  209.     draw_text(x, 42, contents_width, line_height, time, 0)  
  210.     x = text_size(Vocab::ExpireDate).width + 8
  211.     time = @email.expire_date.strftime(Configs::EMAILDATE)
  212.     draw_text(x, 64, contents_width, line_height, time, 0)      
  213.     word_wrap(@email.body).each_with_index do |text, i|
  214.       draw_text(0, line_height * i + 86, contents_width, line_height, text, 1)
  215.     end
  216.     draw_text(0, 230, contents_width, line_height, "#{Vocab.currency_unit}: #{format_number(@email.gold)}", 1)
  217.     if @email.items.size > 0
  218.     bitmap = Cache.system("EmailItems")
  219.       contents.blt(29, 180, bitmap, bitmap.rect)
  220.       contents.font.size = 14    
  221.       @email.items.each_with_index{|item, index|
  222.         x = 32 + (index * 34)
  223.         nitem = $game_party.item_object(item[0], item[1])
  224.         draw_icon(nitem.icon_index, x, 183)
  225.         draw_text(x, 210, 30, line_height, "x#{item[2]}", 1)
  226.         draw_icon(Configs::COLLECTED_MAIL, x, 183) if @email.state == 1
  227.       }    
  228.     end
  229.   end
  230.  
  231.   def update
  232.     super
  233.     hiding = true    
  234.     if @email
  235.       @email.items.each_with_index { |item, index|
  236.         if in_area?(40 + (index * 34), 192, 30, 30)
  237.           show_desc($game_party.item_object(item[0], item[1]))
  238.           hiding = false
  239.           break
  240.         end
  241.       }
  242.     end
  243.     hide_desc if hiding
  244.   end
  245.  
  246. end
  247.  
  248. # janela de escrever email jogadores
  249. class Window_EmailWrite < Window_Base
  250.  
  251.   def initialize
  252.     super(adjust_x, 151, 246, 178)
  253.     self.visible = false
  254.     self.closable = true
  255.     self.title = Vocab::WriteEmail
  256.     @send = Button.new(self, 20, 144, Vocab::Send, 80) { send }
  257.     Button.new(self, 146, 144, Vocab::Cancel, 80) { hide }
  258.     @mail_name = Text_Box.new(self, 12, 18, 110, 20, false, Vocab::MailName) { enable_send_button(0)}
  259.     @receiver_name = Text_Box.new(self, 124, 18, 110, Configs::MAX_CHARACTERS, false, Vocab::ReceiverName) { enable_send_button(1)}
  260.     @mail_body = Text_Box.new(self, 12, 42, 222, 100, false, Vocab::Body) { enable_send_button(2)}
  261.     @gold_box = Number_Box.new(self, 116, 66, 80, 6) { enable_send_button(3) }
  262.     @gold_box.value = 0
  263.     @items = []
  264.     @spam = Time.now
  265.     @cursor = 0
  266.     create_desc
  267.   end
  268.  
  269.   def line_height
  270.     20
  271.   end
  272.  
  273.   def adjust_x
  274.     $windows[:email_list].x + $windows[:email_list].width + 2
  275.   end  
  276.  
  277.   def send
  278.     receiver = @receiver_name.text
  279.     name = @mail_name.text
  280.     body = @mail_body.text
  281.     gold = @gold_box.value
  282.     items = []
  283.     @items.each{|item|
  284.       type = $game_party.kind_item(item[0])
  285.       id = item[0].id
  286.       amount = item[1]
  287.       items << ItemMail.new(type, id, amount)
  288.     }
  289.     $network.send_player_write_email(receiver, name, body, gold, items)
  290.     hide
  291.   end
  292.  
  293.   def hide
  294.     @receiver_name.text = ""
  295.     @mail_name.text = ""
  296.     @mail_body.text = ""
  297.     @gold_box.value = 0
  298.     @items = []
  299.     super
  300.   end
  301.  
  302.   def show
  303.     super
  304.     @mail_name.active = true
  305.   end
  306.  
  307.   def refresh
  308.     contents.clear
  309.     bitmap = Cache.system("EmailItems")
  310.     contents.blt(28, 78, bitmap, bitmap.rect)
  311.     contents.font.size = 16
  312.     draw_text(40, 54, contents_width, line_height, "#{Vocab.currency_unit}:")    
  313.     contents.font.size = 14
  314.     @items.each_with_index{|item, index|
  315.       x = 32 + (index * 34)
  316.       draw_icon(item[0].icon_index, x, 81)
  317.       draw_text(x, 108, 30, line_height, "x#{item[1]}", 1)
  318.     }
  319.   end
  320.  
  321.   def enable_send_button(cursor)
  322.     @send.enable = (@receiver_name.text.strip.size >= Configs::MIN_CHARACTERS &&
  323.         @mail_name.text.strip.size >= Configs::MIN_CHARACTERS &&
  324.         @mail_body.text.strip.size >= Configs::MIN_CHARACTERS )
  325.     @cursor = cursor
  326.   end
  327.  
  328.   def update
  329.     super
  330.     update_drop
  331.     double_click
  332.     update_cursor
  333.     update_desc
  334.   end
  335.  
  336.    
  337.   def double_click
  338.     return unless @items.size > 0
  339.     return unless Mouse.dbl_clk?(:L)
  340.     return unless Time.now > @spam
  341.     @items.each_index{|index|
  342.       next unless in_area?(40 + (index * 34), 123, 30, 30)
  343.       @items.delete_at(index)
  344.       @spam = Time.now + 0.2
  345.       refresh
  346.       return
  347.     }
  348.   end
  349.  
  350.   def update_drop
  351.     return if Mouse.press?(:L)
  352.     return unless $cursor.object
  353.     return unless $cursor.type == Enums::Mouse::ITEM
  354.     return unless in_area?
  355.     $windows[:amount].show(Enums::Amount::EMAIL_ITEM, $cursor.object)
  356.   end
  357.  
  358.   def add_item(item, amount)
  359.     return if @items.size >= 5
  360.     existing = @items.find_index{ |obj| obj[0].id == item.id}
  361.     if existing
  362.       amount = [@items[existing][1] + amount, $game_party.item_number(item)].min
  363.       @items[existing][1] = amount
  364.     else
  365.       amount = [amount, $game_party.item_number(item)].min
  366.       @items << [item, amount]
  367.     end
  368.     refresh
  369.   end
  370.  
  371.   def update_cursor
  372.     return unless Input.trigger?(:TAB)
  373.     @cursor = @cursor >= 4 ? 0 : @cursor + 1
  374.     @mail_name.active = @cursor == 0
  375.     @receiver_name.active = @cursor == 1
  376.     @mail_body.active = @cursor == 2
  377.     @gold_box.active = @cursor == 3
  378.   end
  379.  
  380.   def update_desc
  381.     hiding = true
  382.     if @items.size > 0
  383.       @items.each_with_index { |item, index|
  384.         if in_area?(40 + (index * 34), 90, 30, 30)
  385.           show_desc(item[0])
  386.           hiding = false
  387.           break
  388.         end
  389.       }  
  390.     end
  391.     hide_desc if hiding
  392.   end
  393. end
  394.  
  395. # método para a janela de quantidade
  396. class Window_Amount < Window_Base
  397.   def email_item
  398.     return unless $windows[:email_write].visible
  399.     amount = [@amount_box.value, Configs::MAX_ITEMS].min
  400.     return if $game_party.item_number(@item) < amount
  401.     if @item.soulbound?
  402.       $error_msg = Vocab::SoulboundItem
  403.       return
  404.     end
  405.     $windows[:email_write].add_item(@item, amount)
  406.   end
  407. end
  408.  
  409. #classe do $game_player
  410. class Game_Player < Game_Character
  411.   attr_accessor :emails
  412. end
  413.  
  414. #janela de escrever emails de administradores
  415. class Window_AdminEmailWrite < Window_Base
  416.  
  417.   def initialize
  418.     super(adjust_x, 151, 246, 226)
  419.     self.visible = false
  420.     self.closable = true
  421.     create_desc
  422.     self.title = Vocab::WriteEmail
  423.     @send = Button.new(self, 20, 192, Vocab::Send, 80) { send }
  424.     Button.new(self, 146, 192, Vocab::Cancel, 80) { hide }
  425.     @mail_name = Text_Box.new(self, 12, 18, 110, 20, false, Vocab::MailName) { enable_send_button(0)}
  426.     @receiver_name = Text_Box.new(self, 124, 18, 110, Configs::MAX_CHARACTERS, false, Vocab::ReceiverName) { enable_send_button(1)}
  427.     @mail_body = Text_Box.new(self, 12, 42, 222, 100, false, Vocab::Body) { enable_send_button(2)}
  428.     @gold_box = Number_Box.new(self, 116, 66, 80, 6) { enable_send_button(3) }
  429.     @prev_button = Image_Button.new(self, 134, 90, 'Left') { prev_item_type }
  430.     @next_button = Image_Button.new(self, 214, 90, 'Right') { next_item_type }
  431.     @amount_box = Number_Box.new(self, 74, 113, 56, 5) { enable_send_button(5)}
  432.     @item_box = Number_Box.new(self, 14, 113, 56, 5) { enable_send_button(4)}
  433.     @item_button = Button.new(self, 134, 112, Vocab::AddItem, 98) { add_item }    
  434.     @gold_box.value = 0
  435.     @items = []
  436.     @spam = Time.now
  437.     @cursor = 0
  438.     @item_type = 1
  439.   end
  440.  
  441.   def adjust_x
  442.     $windows[:panel].x + $windows[:panel].width + 2
  443.   end
  444.  
  445.   def line_height
  446.     20
  447.   end
  448.  
  449.   def send
  450.     receiver = @receiver_name.text
  451.     name = @mail_name.text
  452.     body = @mail_body.text
  453.     gold = @gold_box.value
  454.     items = []
  455.     @items.each{|item|
  456.       type = $game_party.kind_item(item[0])
  457.       id = item[0].id
  458.       amount = item[1]
  459.       items << ItemMail.new(type, id, amount)
  460.     }
  461.     $network.send_player_write_email(receiver, name, body, gold, items, true)
  462.     hide
  463.   end
  464.  
  465.   def hide
  466.     @receiver_name.text = ""
  467.     @mail_name.text = ""
  468.     @mail_body.text = ""
  469.     @gold_box.value = 0
  470.     @items = []
  471.     @cursor = 0
  472.     @item_type = 1
  473.     super
  474.   end
  475.  
  476.   def show
  477.     super
  478.     @mail_name.active = true
  479.     enable_send_button(0)
  480.   end
  481.  
  482.   def refresh
  483.     contents.clear
  484.     bitmap = Cache.system("EmailItems")
  485.     contents.blt(28, 126, bitmap, bitmap.rect)
  486.     contents.font.size = 16
  487.     draw_text(40, 54, contents_width, line_height, "#{Vocab.currency_unit}:")    
  488.     case @item_type
  489.     when 1
  490.       item_type = Vocab::Item
  491.     when 2
  492.       item_type = Vocab.weapon
  493.     when 3
  494.       item_type = Vocab.armor
  495.     end
  496.     draw_text(122, 76, 98, line_height, item_type, 1)    
  497.     contents.font.size = 14
  498.     draw_text(2, 78, 136, line_height, Vocab::ID)
  499.     draw_text(62, 78, 136, line_height, "#{Vocab::Amount}:")    
  500.     @items.each_with_index{|item, index|
  501.       x = 28 + (index * 34)
  502.       draw_icon(item[0].icon_index, x+3, 129)
  503.       draw_text(x, 156, 30, line_height, "x#{item[1]}", 1)
  504.     }
  505.   end
  506.  
  507.   def enable_send_button(cursor)
  508.     @send.enable = (@mail_name.text.strip.size >= Configs::MIN_CHARACTERS &&
  509.         @mail_body.text.strip.size >= Configs::MIN_CHARACTERS )
  510.     @item_button.enable = (@amount_box.value > 0 && @item_box.value > 0)
  511.     @cursor = cursor
  512.   end
  513.  
  514.   def update
  515.     super
  516.     update_desc
  517.     double_click
  518.     update_cursor
  519.   end
  520.  
  521.   def double_click
  522.     return unless @items.size > 0
  523.     return unless Mouse.dbl_clk?(:L)
  524.     return unless Time.now > @spam
  525.     @items.each_index{|index|
  526.       next unless in_area?(40 + (index * 34), 138, 30, 30)
  527.       @items.delete_at(index)
  528.       @spam = Time.now + 0.2
  529.       refresh
  530.       return
  531.     }
  532.   end
  533.  
  534.   def add_item
  535.     return if @items.size >= 5 || @item_box.value == 0 || @amount_box.value == 0
  536.     item = $game_party.item_object(@item_type, @item_box.value)
  537.     return unless item
  538.     amount = @amount_box.value
  539.     existing = @items.find_index{ |obj| obj[0].id == item.id}
  540.     if existing
  541.       @items[existing][1] += amount
  542.     else
  543.       @items << [item, amount]
  544.     end
  545.     refresh
  546.     @amount_box.value = 0
  547.     @item_box.value = 0
  548.   end
  549.  
  550.   def update_cursor
  551.     return unless Input.trigger?(:TAB)
  552.     @cursor = @cursor >= 4 ? 0 : @cursor + 1
  553.     @mail_name.active = @cursor == 0
  554.     @receiver_name.active = @cursor == 1
  555.     @mail_body.active = @cursor == 2
  556.     @gold_box.active = @cursor == 3
  557.     @item_box.active = @cursor == 4
  558.     @amount_box.active = @cursor == 5
  559.   end
  560.  
  561.   def prev_item_type
  562.     @item_type = @item_type > 1 ? @item_type - 1 : 3
  563.     refresh
  564.   end
  565.  
  566.   def next_item_type
  567.     @item_type = @item_type < 3 ? @item_type + 1 : 1
  568.     refresh
  569.   end
  570.  
  571.   def update_desc
  572.     hiding = true
  573.     if @items.size > 0
  574.       @items.each_with_index { |item, index|
  575.         if in_area?(40 + (index * 34), 138, 29, 29)
  576.           show_desc(item[0])
  577.           hiding = false
  578.           break
  579.         end
  580.       }
  581.     end
  582.     hide_desc if hiding
  583.   end  
  584.  
  585. end
Add Comment
Please, Sign In to add comment