ForeverZer0

[RMXP] Pickpocket 1.5

May 21st, 2011
480
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 14.48 KB | None | 0 0
  1. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
  2. # Pickpocket Ability
  3. # Author: ForeverZer0
  4. # Date: 5.4.2011
  5. # Version: 1.5
  6. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
  7. # Version History:
  8. #   v.1.0 - Original Release
  9. #   v.1.1 - Added configuration for Input
  10. #   v.1.2 - More efficient and improved method of gathering pickpocket data
  11. #         - No longer requires comment codes to be in brackets []
  12. #           (Old configurations will still work, though)
  13. #         - Configurable search codes
  14. #         - No longer requires 'Pickpocket' comment for initialization
  15. #         - Consolidated various class methods/variables
  16. #         - Better looking pickpocket result window, and got rid of annoying bug
  17. #           that would 'talk' to event when exiting result window
  18. #         - Added config for font color of result item
  19. #         - Improved coding/compatability
  20. #   v.1.3 - Removed from Zer0 Add-On Collection
  21. #         - Optimized code
  22. #         - Added a TOTAL_ATTEMPTS_VARIABLE
  23. #         - Added ability to use a single comment instead of three in a row
  24. #   v.1.4 - Added switch to turn system ON/OFF
  25. #         - Made the item requirement optional (Thanks, GrieverSoft)
  26. #         - Improved the result window. Now draws icons.
  27. #   v.1.5 - Reconfigured to allow for weapons to also add pickpocket ability
  28. #         - Created configuration to allow for different equipment to give
  29. #           bonuses to the odds of a successful steal
  30. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
  31. #
  32. # Explanation:
  33. #
  34. #   - Anybody who played the PSX game Star Ocean will know exactly what this is.
  35. #     It is basically a system that will allow you to pickpocket NPCs to recieve
  36. #     various items, weapons, and armors if you have a certain accessory.
  37. #
  38. # Features:
  39. #  
  40. #   - Easy, quick configuration to setup each event
  41. #   - Variables log all successes and failures for easy merging into an
  42. #     Affection System, Good & Evil System, etc.
  43. #
  44. # Instructions:
  45. #
  46. #   - Setup the few configurations below.  
  47. #   - This script uses comments in the event's pages. Here's how to configure:
  48. #    
  49. #     ** In a single comment or consecutive single line comments *
  50. #
  51. #       Chance = X     - where X is equal to the percentage of
  52. #                        a successful pickpocket. (0 - 100)
  53. #    
  54. #       Type = Y       - where Y is the type of item that will be recieved (0-2)
  55. #                         0 = Item
  56. #                         1 = Weapon
  57. #                         2 = Armor
  58. #    
  59. #       ItemID = Z     - where Z is equal to the database ID of the item, weapon,
  60. #                        or armor (based off of the third comment).
  61. #
  62. #   That's it for setting up events. There are a few more configurations below.
  63. #   For a player to use the ability, they have to have the "Bandit's Gloves"
  64. #   equipped, or whatever you want to call it (see below), and press the Z button
  65. #   (configurable) while touching an event and a pickpocket attempt will be made.
  66. #
  67. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
  68. #                           BEGIN CONFIGURATION
  69. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
  70.  
  71. module Pickpocket
  72.  
  73.   #-----------------------------------------------------------------------------
  74.   # The following two methods define equipment that can offer the ability to
  75.   # pickpocket (if ITEM_REQUIRE), and the bonus that different equipment can
  76.   # give. In each respective method for armors and weapons, any ID that has
  77.   # a return value for it will be an item that unlocks the pickpocket ability
  78.   # if equipped. The returned value will define the bonus percentage that the
  79.   # item gives to the overall odds of success.
  80.   #
  81.   # EXAMPLE:
  82.   #
  83.   #         when 34 then 10
  84.   #
  85.   #   This does two things: Lets the weapon/armor with ID:34 provide the ability
  86.   #   to steal if equipped, and adds a 10% bonus to the success rate.
  87.   #-----------------------------------------------------------------------------
  88.  
  89.   def self.armors(armor_id)
  90.     return case armor_id
  91.     # when ARMOR_ID then PERCENT_ADDED
  92.     when 33 then 0  # Bandit's Glove
  93.     when 34 then 10 # Thief's Glove
  94.     when 35 then 25 # Magician's Hand
  95.     end
  96.   end
  97.  
  98.   def self.weapons(weapon_id)
  99.     return case weapon_id
  100.     # when WEAPON_ID then PERCENT_ADDED
  101.     when 32 then 0
  102.     end
  103.   end
  104.  
  105.   # Define any bonuses that are given for having a specific actor in the party.
  106.   def self.actor_bonus(actor_id)
  107.     return case actor_id
  108.     # when ACTOR_ID then PERCENT_ADDED
  109.     when 1 then 3
  110.     else
  111.       0 # Default case. Do not edit.
  112.     end
  113.   end
  114.  
  115.   PICKPOCKET_SWITCH = 20
  116.   # ID of the switch that will turn the system ON/OFF.
  117.  
  118.   SUCCESS_SE = ['055-Right01', 80, 100]
  119.   # SE played when attempt is successful [FILENAME, VOLUME, PITCH]
  120.   FAIL_SE    = ['057-Wrong01', 80, 100]
  121.   # SE played when attempt fails [FILENAME, VOLUME, PITCH]
  122.  
  123.   SUCCESS_VARIABLE = 1
  124.   # In-game variable that will be equal to total successful pickpockets
  125.   FAILURE_VARIABLE = 2
  126.   # In-game variable that will be equal to total unsuccessful pickpockets
  127.   TOTAL_ATTEMPTS_VARIABLE = 3
  128.   # Variable that will be equal to total attempts, successful or not.
  129.  
  130.   ITEM_REQUIRE = true
  131.   # Set to true/false. Determines if an item is required to use the ability.
  132.  
  133.   STEAL_BUTTON = Input::Z
  134.   # This will be the button that is used to pickpocket events, mind you this the
  135.   # the game button, not just the button on your keyboard.
  136.  
  137.   CHANCE_STRING = 'Chance = '
  138.   TYPE_STRING = 'Type = '
  139.   ITEM_ID_STRING = 'ItemId = '
  140.   # These are the strings that the system searches for in event's comments. If
  141.   # you would like something different, change them. It will match the number
  142.   # that immediately follows them.
  143.  
  144.   RESULT_FONT_COLOR = Color.new(128, 255, 128)
  145.   # This will be the font color that the item is written in when the result
  146.   # of a successful pickpocket is displayed on-screen. (Red, Green, Blue)
  147.  
  148.   USE_MODIFIER = false
  149.   # If true, will apply a formula using the party's dexterity to get a
  150.   # small bonus to the chance of success. (below)
  151.  
  152. #-------------------------------------------------------------------------------
  153. # * Modifier Formula
  154. #
  155. #   (TOTAL_PARTY_DEX รท PARTY_SIZE) = X
  156. #  
  157. #   (Square Root of X) * 0.66 = MODIFIER
  158. #
  159. #   The modifier is added to the chance. It's not much, but at higher levels,
  160. #   it can add a different dynamic to pickpocketing. In a quick test using the
  161. #   default curves, it's about a 5 point bonus at level 1, and with the same
  162. #   actors all at level 99, it is about a 16 point bonus. Even with the entire
  163. #   party all having 999 dexterity, the bonus will not exceed 21 points, which
  164. #   I feel is an appropriate curve. Check out the method and fiddle around
  165. #   with the '0.66' if you want to alter it. Just bust out a calculator and plug
  166. #   the formula in real quick to see what values your getting.
  167. #
  168. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
  169. #                         END CONFIGURATION
  170. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
  171. end
  172.  
  173. #===============================================================================
  174. # ** Game_Map
  175. #===============================================================================
  176.  
  177. class Game_Map
  178.  
  179.   attr_reader   :steal_data   # Array of pickpocket events, remade for each map
  180.   attr_accessor :attempted    # Logs all attempted steals for each map
  181.  
  182.   alias zer0_pickpocket_init initialize
  183.   def initialize
  184.     @steal_data, @attempted = [], {}
  185.     zer0_pickpocket_init
  186.   end
  187.  
  188.   alias zer0_pickpocket_map setup
  189.   def setup(map_id)
  190.    unless @attempted.has_key?(map_id)
  191.      @attempted[map_id] = []
  192.    end
  193.    zer0_pickpocket_map(map_id)
  194.    refresh_pickpocket
  195.  end
  196.  
  197.   def comment_code(string)
  198.     # Returns array of event IDs with matching number after 'string'
  199.     array = []
  200.     @map.events.each_key {|key|
  201.       event = @map.events[key]
  202.         event.pages.reverse.each {|page|
  203.           page.list.each_index {|i|
  204.             if [108, 408].include?(page.list[i].code) &&
  205.               page.list[i].parameters[0] =~ /#{string}([0-9]+)/
  206.               array.push([event.id, $1.to_i])
  207.             end
  208.         }}}
  209.     return array
  210.   end
  211.  
  212.   def refresh_pickpocket
  213.     @steal_data.clear
  214.     chance = comment_code(Pickpocket::CHANCE_STRING)
  215.     type = comment_code(Pickpocket::TYPE_STRING)
  216.     item_id = comment_code(Pickpocket::ITEM_ID_STRING)
  217.     chance.each_index {|i|
  218.       id, ch, ty, it = chance[i][0], chance[i][1], type[i][1], item_id[i][1]
  219.       @steal_data.push([id, ch, ty, it])
  220.     }
  221.   end
  222. end
  223.  
  224. #===============================================================================
  225. # ** Game_Player
  226. #===============================================================================
  227.  
  228. class Game_Player
  229.  
  230.   alias zer0_pickpocket_map update
  231.   def update
  232.     zer0_pickpocket_map
  233.     if Input.trigger?(Pickpocket::STEAL_BUTTON) && $game_party.can_pickpocket?
  234.       # Get coordinates/direction in relation to event
  235.       dir_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
  236.       dir_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
  237.       $game_map.steal_data.each_index {|i|
  238.         id = $game_map.steal_data[i][0]
  239.         if $game_map.events[id].x == dir_x && $game_map.events[id].y == dir_y
  240.           return if $game_map.attempted[$game_map.map_id].include?(id)
  241.           pickpocket(i)
  242.           $game_map.attempted[$game_map.map_id].push(id)
  243.         end
  244.       }
  245.     end
  246.   end
  247.  
  248.   def pickpocket(index)
  249.     # Get a random number between 0 - 100
  250.     r = rand(101)
  251.     # Initialize modifier (remains at 0 unless USE_MODIFIER is true)
  252.     modifier = $game_party.equipment_mod
  253.     if Pickpocket::USE_MODIFIER
  254.       $game_party.actors.each_index {|i|
  255.         modifier += $game_party.actors[i].base_dex
  256.       }
  257.       modifier = (modifier / $game_party.actors.size)
  258.       modifier = (Math.sqrt(modifier)) * 0.66
  259.     end
  260.     # Gather the event's pickpocket data from the steal_data list
  261.     chance = ($game_map.steal_data[index][1] + modifier.round)
  262.     item_type = $game_map.steal_data[index][2]
  263.     item_id = $game_map.steal_data[index][3]
  264.     # If the random number is less than the chance, SUCCESS!
  265.     if chance >= r
  266.       $game_system.se_play(RPG::AudioFile.new(*Pickpocket::SUCCESS_SE))
  267.       case item_type
  268.       when 0
  269.         $game_party.gain_item(item_id, 1)
  270.         item = $data_items[item_id]
  271.       when 1
  272.         $game_party.gain_weapon(item_id, 1)
  273.         item = $data_weapons[item_id]
  274.       when 2
  275.         $game_party.gain_armor(item_id, 1)
  276.         item = $data_armors[item_id]
  277.       end
  278.       $game_variables[Pickpocket::SUCCESS_VARIABLE] += 1
  279.       # Set the result of the pickpocket to the screen
  280.       $scene.pickpocket_result(item) if $scene.is_a?(Scene_Map)
  281.     else
  282.       $game_system.se_play(RPG::AudioFile.new(*Pickpocket::FAIL_SE))
  283.       $game_variables[Pickpocket::FAILURE_VARIABLE] += 1
  284.     end
  285.     $game_variables[Pickpocket::TOTAL_ATTEMPTS_VARIABLE] += 1
  286.   end
  287. end
  288.  
  289. #===============================================================================
  290. # ** Game_Party
  291. #===============================================================================
  292.  
  293. class Game_Party
  294.  
  295.   alias pickpocket_init initialize
  296.   def initialize
  297.     pickpocket_init
  298.     # Store pickpocket weapons and armors to prevent checking later
  299.     @pickpocket_weapons = (1..$data_weapons.size).find_all {|i|
  300.       Pickpocket.weapons(i) != nil }
  301.     @pickpocket_armors = (1..$data_armors.size).find_all {|i|
  302.       Pickpocket.armors(i) != nil }
  303.     @mods = []
  304.   end
  305.    
  306.   def can_pickpocket?
  307.     # Check switch
  308.     return false unless $game_switches[Pickpocket::PICKPOCKET_SWITCH]
  309.     # Return false if message window is showing
  310.     return false if $game_temp.message_window_showing
  311.     # Check equipment if required
  312.     if Pickpocket::ITEM_REQUIRE
  313.       @mods = []
  314.       weapons = @pickpocket_weapons.find_all {|id| party_weapons.include?(id) }
  315.       armors = @pickpocket_armors.find_all {|id| party_armors.include?(id) }
  316.       # Add modifiers of found equipment.
  317.       @mods += weapons.collect {|weapon_id| Pickpocket.weapons(weapon_id) }
  318.       @mods += armors.collect {|armor_id| Pickpocket.armors(armor_id) }
  319.       return @mods != []
  320.     end
  321.     return true
  322.   end
  323.    
  324.   def party_weapons
  325.     # Returns array of the party's weapon IDs
  326.     return @actors.collect {|actor| actor.weapon_id }
  327.   end
  328.  
  329.   def party_armors
  330.     # Returns array of party's armor IDs
  331.     armors = []
  332.     $game_party.actors.each {|actor|
  333.       armors.push(actor.armor1_id)
  334.       armors.push(actor.armor2_id)
  335.       armors.push(actor.armor3_id)
  336.       armors.push(actor.armor4_id)
  337.     }
  338.     return armors
  339.   end
  340.  
  341.   def equipment_mod
  342.     actor_bonus = @actors.collect {|actor| Pickpocket.actor_bonus(actor.id) }
  343.     bonus = 0
  344.     actor_bonus.each {|percent| bonus += percent }
  345.     # Returns the highest percentage-adding value of all current equipment.
  346.     return @mods != [] ? (@mods.sort[-1] + bonus) : bonus
  347.   end
  348. end
  349.  
  350. #===============================================================================
  351. # ** Window_Pickpocket
  352. #===============================================================================
  353.  
  354. class Window_Pickpocket < Window_Base
  355.  
  356.   def initialize(item)
  357.     # Initialize window through parent class.
  358.     super(176, 192, 224, 96)
  359.     self.contents = Bitmap.new(width - 32, height - 32)
  360.     self.contents.draw_text(0, 0, self.contents.width, 32, 'Received a', 1)
  361.     self.contents.font.color = Pickpocket::RESULT_FONT_COLOR
  362.     # Calculate coordinates to draw name and icon.
  363.     icon = RPG::Cache.icon(item.icon_name)
  364.     w = 32 + self.contents.text_size(item.name + '!').width
  365.     x = (self.contents.width - w) / 2
  366.     self.contents.blt(x + 4, 32, icon, Rect.new(0, 0, 24, 24))
  367.     self.contents.draw_text(x + 32, 32, w, 32, item.name + '!')
  368.   end
  369. end
  370.  
  371. #===============================================================================
  372. # ** Scene_Map
  373. #===============================================================================
  374.  
  375. class Scene_Map
  376.  
  377.   def pickpocket_result(item)
  378.     # Displays the result on screen in a message.
  379.     window = Window_Pickpocket.new(item)
  380.     loop {
  381.       [Graphics,Input, @spriteset].each {|obj| obj.update }
  382.       break if Input.trigger?(Input::C) || $scene != self
  383.     }
  384.     window.dispose
  385.   end
  386. end
Advertisement
Add Comment
Please, Sign In to add comment