Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. # Tags on actors (that are personas)
  2. # ==============================================================================
  3. # You can specify which actor is a persona by simply adding the following tag:
  4. # <Persona>
  5. # By adding the tag bellow:
  6. # <User: actor_id[, actor_id[, ...]]>
  7. # on a persona actor you can specify the users that can equip the specific
  8. # persona. Remember that for the <User: ...> tag to work the actor must be a
  9. # persona. Also, you can specify as many persona users as you want in the list.
  10. # For convenience, you can set the default users of a persona that doesn't have
  11. # that tag through the options module.
  12. # Personas can't learn an infinite number of skills. You can specify the
  13. # maximum number of skills a persona can learn by using the following tag:
  14. # <Max skills: number>
  15. # The default number of maximum skills for all personas is set to 4, but you can
  16. # change it through the options module! Lastly, a persona has the ability to evolve
  17. # into a stronger one when it reaches a specific arcana rank! You can specify the
  18. # rank of the arcana at which the persona will evolve with the following tag:
  19. # <Evolve at: rank>
  20. # and the persona to which it will evolve to with the following one:
  21. # <Evolve to: persona_name>
  22. # Additionally, you can set arcana rank and player level
  23. # requirements to personas, so that a user can only equip
  24. # that persona when they meet those requirements.
  25. # To apply a minimum arcana rank requirement for a specific
  26. # persona you use the following tag:
  27. # <Arcana rank: rank>
  28. # To apply a minimum player level requirement for a specific persona
  29. # you use the following tag:
  30. # <Player level: level>
  31. # ------------------------------------------------------------------------------
  32. # Tags on actors (that use personas)
  33. # ==============================================================================
  34. # You can specify that a specific actor can use ONLY one (which will be
  35. # automatically equipped) by using the following tag:
  36. # <Persona: actor_id>
  37. # Also, to specify which persona will be equipped in Battle test on a specific
  38. # ctor, you can use the following tag:
  39. # <Battletest persona: actor_id>
  40. # ------------------------------------------------------------------------------
  41. # Tags on classes (Arcana)
  42. # ==============================================================================
  43. # You can specify which classes represent an arcana by adding the tag
  44. # bellow:
  45. # <Arcana>
  46. # Each arcana's current rank is stored in a game variable. Those variables
  47. # can be set for each Arcana separately by adding the following tag:
  48. # <Rank variable: variable_id>
  49. # Of course, you can set the maximum rank of each arcana by adding the
  50. # tag bellow on each arcana:
  51. # <Max rank: rank>
  52. # The default maximum rank is set to 10, but can be changed through the
  53. # options module. As in the original game, each arcana has its own social link(s).
  54. # You can specify who is or are those links by adding the following tags
  55. # to specify by actor id:
  56. # <Social links actors: actor_id[,actor_id[,...]]>
  57. # and to specify by variable id (in which actor ids are stored):
  58. # <Social links actors: actor_id[,actor_id[,...]]>
  59. # As far as naming those social links and their description goes, you can
  60. # use the tag bellow to specify the name of the social link:
  61. # <Social target: name>
  62. # and the one bellow to specify its description:
  63. # <Description: description>
  64. # You can specify the description of an actor's social link by adding
  65. # this tag:
  66. # <Social description: description>
  67. # ------------------------------------------------------------------------------
  68. # Tags on enemies
  69. # ==============================================================================
  70. # There is only one tag that is used on enemies and it specifies the card
  71. # that an enemy can drop:
  72. # <Card drop: card_name, chance>
  73. # The chance is specified by a floating number and not a percentage, for
  74. # example using the tag bellow on an enemy, has a 30% chance to drop the
  75. # Ghoul card:
  76. # <Card drop: Ghoul, 0.3>
  77. # ------------------------------------------------------------------------------
  78. # Add persona to party
  79. # ==============================================================================
  80. # You can add a persona to your party by calling the following script:
  81. # $game_party.add_persona(actor_id)
  82. # It is important to remember that you cannot have duplicate personas in
  83. # your party! Also, for developing purposes a message box will be displayed
  84. # if you try adding an actor as a persona that is not actually a persona!
  85. # Personas can also be acquired through the Shuffle Time that happens after
  86. # a battle and if the enemy troop has dropped any cards. You can learn
  87. # more about Shuffle Time by going to the back of the room.
  88. # ------------------------------------------------------------------------------
  89. # Remove social link through variable
  90. # ==============================================================================
  91. # If you have specified someone as a social link of an arcana via
  92. # variables (see Tags on class (Arcanas)) you can remove a social
  93. # link by setting the specific variable's value to -1. Do remember
  94. # that if you have specified that social link through the actor social
  95. # link tag, then even if you remove that actor they will still be a
  96. # social link. Social links specified via actor ids cannot be removed!
  97. # ------------------------------------------------------------------------------
  98. # Increase/Decrease arcana rank
  99. # ==============================================================================
  100. # You can increase an arcana's rank by making the following script
  101. # call:
  102. # $game_player.arcana_rank_up(arcana_name).
  103. # You can also decrease an arcana's rank by making the following
  104. # script call:
  105. # $game_player.arcana_rank_down(arcana_name).
  106. # The minimum arcana rank can be set though the persona module!
  107. # For convenience you can use the script call bellow to increase the
  108. # arcana's rank by
  109. # multiple ranks:
  110. # $game_party.arcana_rank_up_by(arcana_name, ranks)
  111. # The same can be done to decrease the arcana's rank by multiple ranks
  112. # by making the following script call:
  113. # $game_party.arcana_rank_down_by(arcana_name, ranks)
  114. # ------------------------------------------------------------------------------
  115. # Persona in party or equipped
  116. # ==============================================================================
  117. # You can check if a persona is in the party by using the following
  118. # script call:
  119. # $game_party.persona_in_party(persona_name).
  120. #
  121. # You can check if a persona is currently equipped by simply calling
  122. # the following script:
  123. # $game_party.persona_equipped(persona_name)
  124. #
  125. # Also, you can check if a persona is equipped by a specific actor
  126. # with the following script call:
  127. # $game_party.persona_equipped_by(actor_id, persona_name)
  128. # ------------------------------------------------------------------------------
  129. # Shuffle Time
  130. # ==============================================================================
  131. # Shuffle Time happens after battle and gives the player a chance to
  132. # receive new Persona cards. Shuffle Time happens only if the enemies have
  133. # dropped at least two cards. Of course, you can change this number
  134. # through the options module. There are three types of cards in Shuffle
  135. # Time:
  136. # Persona cards,
  137. # Blank cards and
  138. # Penalty cards.
  139. # When a Blank card is picked, nothing happens whereas when a Penalty
  140. # card is picked, the player gains no battle rewards! There are also
  141. # two different shuffle methods:
  142. # Rotating card either horizontally, diagonally or a combination
  143. # of both and
  144. # Memory match, where player matches two cards and has at most
  145. # five attempts.
  146. # You can change the maximum number of tries the player has through
  147. # the options module! Also, you can force the next Shuffle Time method
  148. # to be a specific one (among the available) by setting the value of
  149. # the variable with ID 1 to the method you want. For example "Horizontal"
  150. # if you want the next Shuffle Time method to be Horizontal or "Matching"
  151. # if you want it to be the Matching one. Of course, you can change which
  152. # variable you want to specify the method, though the options module.
  153. # Lastly, you can call the shuffle scene with whichever cards you want
  154. # by firstly setting the variable with ID 2 to a script call with a
  155. # list of persona names like this:
  156. # ["name_1", "name_2", ...]
  157. # and then by calling the scene with the following command:
  158. # $game_system.shuffle_time
  159. # It is important to remember that you cannot have duplicate personas
  160. # in your party! Additionally, a message box will be displayed if you
  161. # try running Shuffle Time without setting the list of cards to be included!
  162. # You can access the result of the last shuffle time by simply calling
  163. # the following script command:
  164. # $game_system.shuffle_result.
  165. # ------------------------------------------------------------------------------
  166. # Fusion
  167. # ==============================================================================
  168. # Fusion is the system in which two or more personas are combined
  169. # together to create a new persona. You can use the following tag
  170. # bellow on a persona to specify which personas need to be fused to
  171. # create that one:
  172. # <Fusion parents: actor_id1, actor_id2>
  173. # For example, if you use the following tag on Himiko:
  174. # <Fusion parents: 13, 14>
  175. # then when you try fusing Andras with Forneus, the fusion will result
  176. # to... Himiko.
  177. # You can also fuse three personas together to create special
  178. # ones too! To specify the parents of a "special" persona you can
  179. # use the following tag:
  180. # <Special fusion: actor_id1, actor_id2, actor_id3>
  181. # Last but not least! To call the persona fusion scene you use the
  182. # following script call:
  183. # $game_system.fuse_personas(2).
  184. # For the special fusion scene you use the following script call:
  185. # $game_system.fuse_personas(3).
  186. # ------------------------------------------------------------------------------
  187. # Persona and user parameters
  188. # ==============================================================================
  189. # Personas can be equiped through the main menu command called
  190. # "Persona". Personas add percentages of their parameters and
  191. # stats to the actor they're equiped on. The default percentage
  192. # is set to 100%, but can be changed through the persona options
  193. # module. You can also change the percentage of the user's parameters
  194. # that are added to the end result. The default percentage is also
  195. # set to 100% and can be changed though the options module too.
  196. # ==============================================================================
  197. # Mady by vFoggy
  198. # ==============================================================================
  199. #
  200. #-------------------------------------------------------------------------------
  201. # ____ __ __ _ _
  202. # | _ \ ___ _ __ ___ ___ _ __ __ _ | \/ | ___ __| |_ _| | ___
  203. # | |_) / _ \ '__/ __|/ _ \| '_ \ / _` | | |\/| |/ _ \ / _` | | | | |/ _ \
  204. # | __/ __/ | \__ \ (_) | | | | (_| | | | | | (_) | (_| | |_| | | __/
  205. # |_| \___|_| |___/\___/|_| |_|\__,_| |_| |_|\___/ \__,_|\__,_|_|\___|
  206. #
  207. # ___ _ _
  208. # / _ \ _ __ | |_(_) ___ _ __ ___
  209. # | | | | '_ \| __| |/ _ \| '_ \/ __|
  210. # | |_| | |_) | |_| | (_) | | | \__ \
  211. # \___/| .__/ \__|_|\___/|_| |_|___/
  212. # |_|
  213. # Persona Module Options
  214. #-------------------------------------------------------------------------------
  215. module Persona
  216. PERSONA_EXP_GAIN_MULTIPLIER = 1.0
  217.  
  218. # phys, gun, fire, ice, lightning, wind, psi, nuclear, light, dark
  219. PERSONA_ELE_ICON_INDEXES = [528, 529, 530, 531, 532, 533, 534, 535, 536, 537]
  220. # icon index that indicates that indicates the persona's strong element
  221. # -1 will just show "Str"
  222. PERSONA_STRONG_ELE_ICON = -1
  223. # icon index that indicates that indicates the persona's weak element
  224. # -1 will just show "Wk"
  225. PERSONA_WEAK_ELE_ICON = -1
  226. # icon index that indicates that indicates the persona's normal element
  227. # -1 will just show "-"
  228. PERSONA_NORMAL_ELE_ICON = -1
  229.  
  230. # parameter multipliers. if all are the same only one number can be used for all
  231. USER_PARAM_MULTIPLIER = [1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
  232. USER_XPARAM_MULTIPLIER = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
  233. USER_SPARAM_MULTIPLIER = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0]
  234. PERSONA_PARAM_MULTIPLIER = [0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
  235. PERSONA_XPARAM_MULTIPLIER = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
  236. PERSONA_SPARAM_MULTIPLIER = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0]
  237.  
  238. # Name of the persona option in the menu and battle command
  239. PERSONA_MENU_NAME = "Change P." # alternative name for persona.
  240.  
  241. # index of persona command in battle commands window
  242. PERSONA_BATTLE_COMMAND_INDEX = 2
  243. # index of persona command in main menu
  244. PERSONA_MENU_COMMAND_INDEX = 1
  245.  
  246. # name of the button images displayed in the persona list menu window
  247. SELECT_PERSONA_BUTTON_IMG_NAME = "select_persona_button"
  248. EQUIP_PERSONA_BUTTON_IMG_NAME = "equip_persona_button"
  249.  
  250. # better keep a space at the beginning of the text
  251. SELECT_PERSONA_TEXT = " Show status"
  252. EQUIP_PERSONA_TEXT = " Equip persona"
  253. # written on actor's personas list when no personas are available
  254. NO_PERSONAS_MSG = "No available personas."
  255.  
  256. # key used to equip persona
  257. EQUIP_PERSONA_KEY = :X
  258.  
  259. # ids of the default users for a persona that has no users specified
  260. # can be an empty list
  261. DEFAULT_PERSONA_USERS = [1]
  262.  
  263. # if true then skills of both user and persona will appear under user's skill
  264. # list
  265. UNIFIED_SKILLS = true
  266. # when UNIFIED_SKILLS is false, this color is used to differentiate persona's
  267. # skills from user's skills in the battle's skills list.
  268. # use Color.new(0, 0, 0) for normal color
  269. PERSONA_SKILLS_COLOR = Color.new(0, 255, 0) # green
  270. # index from which the persona's skill commands start (for multiple skill types)
  271. PERSONA_SKILLS_COMMAND_INDEX = 4
  272.  
  273. #-------------------------------------------------------------------------------
  274. # ____ _ _ _ _ _____ _
  275. # / ___|| | _(_) | | | ___|__ _ __ __ _ ___| |_
  276. # \___ \| |/ / | | | | |_ / _ \| '__/ _` |/ _ \ __|
  277. # ___) | <| | | | | _| (_) | | | (_| | __/ |_
  278. # |____/|_|\_\_|_|_| |_| \___/|_| \__, |\___|\__|
  279. # |___/
  280. # __ __ _ _ ___ _ _
  281. # | \/ | ___ __| |_ _| | ___ / _ \ _ __ | |_(_) ___ _ __ ___
  282. # | |\/| |/ _ \ / _` | | | | |/ _ \ | | | | '_ \| __| |/ _ \| '_ \/ __|
  283. # | | | | (_) | (_| | |_| | | __/ | |_| | |_) | |_| | (_) | | | \__ \
  284. # |_| |_|\___/ \__,_|\__,_|_|\___| \___/| .__/ \__|_|\___/|_| |_|___/
  285. # |_|
  286. # Skill Forget Module Options
  287. #-------------------------------------------------------------------------------
  288. # max number of skills a persona can have
  289. DEFAULT_MAX_PERSONA_SKILLS = 8
  290.  
  291. #-------------------------------------------------------------------------------
  292. # _ __ __ _ _
  293. # / \ _ __ ___ __ _ _ __ __ _ | \/ | ___ __| |_ _| | ___
  294. # / _ \ | '__/ __/ _` | '_ \ / _` | | |\/| |/ _ \ / _` | | | | |/ _ \
  295. # / ___ \| | | (_| (_| | | | | (_| | | | | | (_) | (_| | |_| | | __/
  296. # /_/ \_\_| \___\__,_|_| |_|\__,_| |_| |_|\___/ \__,_|\__,_|_|\___|
  297. #
  298. # ___ _ _
  299. # / _ \ _ __ | |_(_) ___ _ __ ___
  300. # | | | | '_ \| __| |/ _ \| '_ \/ __|
  301. # | |_| | |_) | |_| | (_) | | | \__ \
  302. # \___/| .__/ \__|_|\___/|_| |_|___/
  303. # |_|
  304. # Arcana Module Options
  305. #-------------------------------------------------------------------------------
  306. # min arcana rank. arcanas start with 0 rank and will be shown only
  307. # when at MIN_RANK or higher
  308. MIN_RANK = 1
  309. DEFAULT_MAX_RANK = 10 # default maximum rank of persona arcana
  310.  
  311. # folder of the arcana cards images
  312. ARCANA_IMG_FOLDER = "Persona/Arcanas/" # inside Graphics folder
  313.  
  314. # name of the social links in the menu
  315. ARCANA_MENU_NAME = "Confidants" # alternative name for Social Links
  316. ARCANA_MENU_COMMAND_INDEX = 2
  317.  
  318. # file names for the arcana rank progression bar
  319. ARCANA_RANKS_BAR_IMG_NAME = "bar"
  320. ARCANA_PROGRESS_IMG_NAME = "progress"
  321. ARCANA_PROGRESS_EMPTY_IMG_NAME = "progress_empty"
  322.  
  323. #-------------------------------------------------------------------------------
  324. # _____ _ _ _ __ __ _ _
  325. # | ____|_ _____ | |_ _| |_(_) ___ _ __ | \/ | ___ __| |_ _| | ___
  326. # | _| \ \ / / _ \| | | | | __| |/ _ \| '_ \ | |\/| |/ _ \ / _` | | | | |/ _ \
  327. # | |___ \ V / (_) | | |_| | |_| | (_) | | | | | | | | (_) | (_| | |_| | | __/
  328. # |_____| \_/ \___/|_|\__,_|\__|_|\___/|_| |_| |_| |_|\___/ \__,_|\__,_|_|\___|
  329. #
  330. # ___ _ _
  331. # / _ \ _ __ | |_(_) ___ _ __ ___
  332. # | | | | '_ \| __| |/ _ \| '_ \/ __|
  333. # | |_| | |_) | |_| | (_) | | | \__ \
  334. # \___/| .__/ \__|_|\___/|_| |_|___/
  335. # |_|
  336. # Evolution Module Options
  337. #-------------------------------------------------------------------------------
  338. # ID of common event that runs when a persona is being evolved
  339. COMMON_EVENT_ID = 1
  340.  
  341. # variable id in which the name of the persona that is being evolved is stored
  342. EVOLVING_PERSONA_VAR_ID = 13
  343. # variable id in which the name of the persona to which the persona will be evolved
  344. RESULTING_PERSONA_VAR_ID = 14
  345.  
  346. #-------------------------------------------------------------------------------
  347. # _____ _ __ __ _ _
  348. # | ___| _ ___(_) ___ _ __ | \/ | ___ __| |_ _| | ___
  349. # | |_ | | | / __| |/ _ \| '_ \ | |\/| |/ _ \ / _` | | | | |/ _ \
  350. # | _|| |_| \__ \ | (_) | | | | | | | | (_) | (_| | |_| | | __/
  351. # |_| \__,_|___/_|\___/|_| |_| |_| |_|\___/ \__,_|\__,_|_|\___|
  352. #
  353. # ___ _ _
  354. # / _ \ _ __ | |_(_) ___ _ __ ___
  355. # | | | | '_ \| __| |/ _ \| '_ \/ __|
  356. # | |_| | |_) | |_| | (_) | | | \__ \
  357. # \___/| .__/ \__|_|\___/|_| |_|___/
  358. # |_|
  359. # Fusion Module Options
  360. #-------------------------------------------------------------------------------
  361. # list of actor ids whose personas can be fused.
  362. # example: if [1, 4, 6] then the player can fuse personas that belong to
  363. # the actors with id 1, 4 and 6
  364. CAN_USE_ACTORS_PERSONAS = [1]
  365.  
  366. # color of the special fusion result in the fusion results window. RGB values
  367. SPECIAL_FUSION_COLOR = Color.new(255, 255, 0) # yellow
  368.  
  369. # method to calculate the fusion resulting persona extra exp
  370. def self.FUSION_EXP_CALC(persona)
  371. # you can use this method to calculate the total experience the persona
  372. # child will earn from the fusion process. keep the first line
  373. return 0 unless persona.persona? || persona.nil?
  374. [persona.arcana_rank, 0].max * 1000 + persona.level * 1000 + rand(5) * 100 + rand(10) * 10 + rand(10)
  375. end
  376.  
  377. # if true, then the player has to choose the fusing personas in the order
  378. # in which they are specified in the tag.
  379. ORDER_MATTERS = false
  380.  
  381. #-------------------------------------------------------------------------------
  382. # ____ _ __ __ _ __ __ _ _
  383. # / ___|| |__ _ _ / _|/ _| | ___ | \/ | ___ __| |_ _| | ___
  384. # \___ \| '_ \| | | | |_| |_| |/ _ \ | |\/| |/ _ \ / _` | | | | |/ _ \
  385. # ___) | | | | |_| | _| _| | __/ | | | | (_) | (_| | |_| | | __/
  386. # |____/|_| |_|\__,_|_| |_| |_|\___| |_| |_|\___/ \__,_|\__,_|_|\___|
  387. #
  388. # ___ _ _
  389. # / _ \ _ __ | |_(_) ___ _ __ ___
  390. # | | | | '_ \| __| |/ _ \| '_ \/ __|
  391. # | |_| | |_) | |_| | (_) | | | \__ \
  392. # \___/| .__/ \__|_|\___/|_| |_|___/
  393. # |_|
  394. # Shuffle Module Options
  395. #-------------------------------------------------------------------------------
  396. # possible window positions
  397. WINDOW_POSITIONS = [
  398. "BL", # Bottom Left
  399. "BR", # Bottom Right
  400. "TL", # Top Left
  401. "TR" # Top Right
  402. ]
  403.  
  404. # folder of images of cards
  405. CARD_IMG_FOLDER = "Persona/Cards/" # inside Graphics folder
  406. # name of the image of the back of the cards
  407. CARD_BACK_NAME = "Back" # should be inside CARD_IMG_FOLDER
  408. # background file of shuffle time
  409. SHUFFLE_BACKGROUND = "Shuffle_Background" # should be inside Persona folder
  410.  
  411. # index of window position (WINDOW_POSITIONS) for shuffle time accept window
  412. ACCEPT_POSITION = 1
  413. # index of window position (WINDOW_POSITIONS) that displays the tries left
  414. # for the matching method
  415. COUNTER_POSITION = 1
  416.  
  417. MATCHING_TRIES = 5
  418.  
  419. # max numbers of cards displayed per row in shuffle time (before shuffling
  420. # and during the matching) must be set according to the image size of the
  421. # cards if there are too many per row they will go out of screen
  422. MAX_CARDS_PER_ROW = 5
  423.  
  424. # minimum number of penalty and blank cards a shuffle time must have
  425. MIN_PENALTY_CARDS = 1
  426. MIN_BLANK_CARDS = 1
  427. # maximum number of penalty and blank cards a shuffle time must have
  428. MAX_PENALTY_CARDS = 2
  429. MAX_BLANK_CARDS = 2
  430. # number of cards required to be dropped (without blank and penalty)
  431. # to initiate shuffle time
  432. MIN_CARDS_TO_SHUFFLE = 2
  433.  
  434. # variable id from which the next shuffle method is set
  435. FORCE_SHUFFLE_METHOD_VAR_ID = 10
  436.  
  437. # variable id from which the next shuffle cards are set
  438. SHUFFLE_ITEMS_VAR_ID = 11
  439. # if true then duplicates cards will be included in the shuffle time
  440. # does not apply to blank and penalty cards. use the
  441. # MIN/MAX_PENALTY/BLANK_CARDS options
  442. ALLOW_DUPLICATES = false
  443. # if true then the cards set with the variable will be filtered according
  444. # to MIN/MAX_PENALTY_CARDS etc.
  445. FILTER_MANUAL_CARDS = false
  446.  
  447. # Messages
  448. # message displayed when player loses at the matching shuffle method
  449. MATCHING_LOSE_MESSAGE = "You lost!"
  450.  
  451. # message displayed when no card was drawn (only happens in matching method)
  452. NO_CARD_DRAW_MSG = "You didn't draw any card!"
  453. # message dispalyed in the battle results when no card is drawn
  454. NO_CARD_RESULT_MSG = "Nothing happened."
  455.  
  456. # message displayed when the blank card is drawn
  457. BLANK_CARD_DRAW_MSG = "You drew a Blank Card..."
  458. # message dispalyed in the battle results when the blank card is drawn
  459. BLANK_CARD_RESULT_MSG = "Nothing happened."
  460.  
  461. # message displayed when the penalty card is drawn
  462. PENALTY_CARD_DRAW_MSG = "You drew a Penalty Card..."
  463. # message displayed in the battle results when the penalty card is drawn
  464. PENALTY_CARD_RESULT_MSG = "All the rewards you gained from this battle \nhave vanished..."
  465.  
  466. # message that is displayed when a card is picked. must have the %s which
  467. # is where the persona's name will be put
  468. PERSONA_CARD_DRAW_MSG = "You drew a card of the Persona %s!"
  469.  
  470. # [Audio file directory, Volume level, Pitch]
  471. # music to play while shuffling
  472. SHUFFLE_BGM = ["Audio/BGM/Field2", 100, 100]
  473. # could be the sound of cards
  474. SHUFFLE_BGS = nil
  475. SHUFFLE_PENALTY_SOUND = ["Audio/SE/Collapse1", 100, 100]
  476. SHUFFLE_BLANK_SOUND = ["Audio/SE/Blind", 100, 100] # same sound plays for no card too
  477. SHUFFLE_CARD_SOUND = ["Audio/SE/Applause2", 100, 100]
  478.  
  479. # you can change the method below and make it decide the shuffle method
  480. # however you want
  481. def self.SHUFFLE_SELECTION(cards)
  482. if cards.size <= 6
  483. return ["Horizontal", "Diagonal"].sample
  484. elsif cards.size <= 10
  485. return "Combination"
  486. elsif cards.size <= 15
  487. return "Matching"
  488. end
  489. end
  490. end
  491. #-------------------------------------------------------------------------------
  492. #-------------------------------------------------------------------------------
  493. # _____ _ __ _ _
  494. # | ____|_ __ __| | ___ / _| ___ _ __ | |_(_) ___ _ __ ___
  495. # | _| | '_ \ / _` | / _ \| |_ / _ \| '_ \| __| |/ _ \| '_ \/ __|
  496. # | |___| | | | (_| | | (_) | _| | (_) | |_) | |_| | (_) | | | \__ \
  497. # |_____|_| |_|\__,_| \___/|_| \___/| .__/ \__|_|\___/|_| |_|___/
  498. # |_|
  499. # _
  500. # _ __ __ _ _ __| |_
  501. # | '_ \ / _` | '__| __|
  502. # | |_) | (_| | | | |_
  503. # | .__/ \__,_|_| \__|
  504. # |_|
  505. #
  506. #-------------------------------------------------------------------------------
  507. #-------------------------------------------------------------------------------
  508.  
  509. #-------------------------------------------------------------------------------
  510. # ____ __ __ _ _
  511. # | _ \ ___ _ __ ___ ___ _ __ __ _ | \/ | ___ __| |_ _| | ___
  512. # | |_) / _ \ '__/ __|/ _ \| '_ \ / _` | | |\/| |/ _ \ / _` | | | | |/ _ \
  513. # | __/ __/ | \__ \ (_) | | | | (_| | | | | | (_) | (_| | |_| | | __/
  514. # |_| \___|_| |___/\___/|_| |_|\__,_| |_| |_|\___/ \__,_|\__,_|_|\___|
  515. #
  516. # Persona Module
  517. #-------------------------------------------------------------------------------
  518. class RPG::Actor < RPG::BaseItem
  519. def persona?
  520. note =~ /<Persona>/ ? true : false
  521. end
  522.  
  523. def users
  524. # returns list of actors that can use specific persona
  525. matches = /<User: (\d+(,[ ]?\d+)*)?>/.match(note)
  526. return Persona::DEFAULT_PERSONA_USERS if matches.nil?
  527. user_str = matches[1]
  528. user_str.split(",").collect{ |i| i.to_i }
  529. end
  530.  
  531. def only_persona
  532. note =~ /<Persona: (\d+)>/ ? $1.to_i : nil
  533. end
  534.  
  535. def min_player_level
  536. # min player level required to fuse persona
  537. note =~ /<Player level: (\d+)>/ ? $1.to_i : 0
  538. end
  539.  
  540. def battletest_persona
  541. # get persona to use for battletest
  542. note =~ /<Battletest persona: (\d+)>/ ? $1.to_i : 0
  543. end
  544. end
  545.  
  546. module Cache
  547. def self.persona_file(filename)
  548. load_bitmap("Graphics/Persona/", filename)
  549. end
  550. end
  551.  
  552. module DataManager
  553. class <<self
  554. alias persona_cgo create_game_objects
  555. def create_game_objects
  556. persona_cgo
  557. $game_personas = Game_Personas.new
  558. end
  559. end
  560. end
  561.  
  562. class Game_Actor < Game_Battler
  563. include Persona
  564.  
  565. attr_reader :users, :only_persona, :min_player_level
  566. alias persona_su setup
  567. def setup(actor_id)
  568. @persona = nil
  569. @changed_persona = false
  570. persona_su(actor_id)
  571. setup_persona
  572. end
  573.  
  574. def setup_persona
  575. @is_persona = actor.persona?
  576. @users = actor.users
  577. @only_persona = actor.only_persona
  578. @min_player_level = actor.min_player_level
  579. end
  580.  
  581. def persona?
  582. @is_persona
  583. end
  584.  
  585. def persona
  586. @persona
  587. end
  588.  
  589. def can_change_persona
  590. !@changed_persona
  591. end
  592.  
  593. def persona_change_ok?(persona)
  594. return false if @changed_persona
  595. return false if @persona == persona
  596. return false if !can_equip_persona(persona)
  597. return true
  598. end
  599.  
  600. def change_persona(persona)
  601. return if !persona_change_ok?(persona)
  602. return if $game_party.personas.find{|p| p.id == persona.id}.nil?
  603. # when changing persona keep the same hp rate the actor had with the
  604. # previous one
  605.  
  606. prev_hp_rate = hp_rate
  607. prev_mp_rate = mp_rate
  608.  
  609. @persona = persona
  610. @changed_persona = true if $game_party.in_battle
  611. refresh
  612.  
  613. @hp = (mhp * prev_hp_rate).to_i
  614. @mp = (mmp * prev_mp_rate).to_i
  615. end
  616.  
  617. def force_change_persona(persona_id)
  618. return if $game_party.personas.find{|p| p.id == persona_id}.nil?
  619. # force change persona without checking if it is ok
  620. prev_hp_rate = hp_rate
  621. prev_mp_rate = mp_rate
  622.  
  623. @persona = $game_personas[persona_id]
  624. @changed_persona = true if $game_party.in_battle
  625. refresh
  626.  
  627. @hp = (mhp * prev_hp_rate).to_i
  628. @mp = (mmp * prev_mp_rate).to_i
  629. end
  630.  
  631. def remove_persona
  632. prev_hp_rate = hp_rate
  633. prev_mp_rate = mp_rate
  634.  
  635. @persona = nil
  636.  
  637. @hp = (mhp * prev_hp_rate).to_i
  638. @mp = (mmp * prev_mp_rate).to_i
  639. end
  640.  
  641. alias persona_ast added_skill_types
  642. def added_skill_types
  643. # get skill types of actor and their persona
  644. skill_types = persona_ast
  645. skill_types |= persona_added_skill_types if UNIFIED_SKILLS
  646. return skill_types
  647. end
  648.  
  649. alias persona_s skills
  650. def skills
  651. # get skills of actor and their persona
  652. skills = persona_s
  653. skills |= persona_skills if UNIFIED_SKILLS
  654. return skills
  655. end
  656.  
  657. def persona_skills
  658. return @persona.skills if !persona? && !@persona.nil?
  659. return []
  660. end
  661.  
  662. def persona_added_skill_types
  663. return @persona.added_skill_types if !persona? && !@persona.nil?
  664. return []
  665. end
  666.  
  667. alias persona_param param
  668. def param(param_id)
  669. # get the value of the actor's parameter
  670. value = persona_param(param_id)
  671. if !persona? && !@persona.nil?
  672. # get the actor's and persona's multiplier and add both of their parameters
  673. # with their respective multiplier
  674. user_mult = USER_PARAM_MULTIPLIER.is_a?(Array) ? USER_PARAM_MULTIPLIER[param_id] : USER_PARAM_MULTIPLIER
  675. persona_mult = PERSONA_PARAM_MULTIPLIER.is_a?(Array) ? PERSONA_PARAM_MULTIPLIER[param_id] : PERSONA_PARAM_MULTIPLIER
  676. value = (value * user_mult) + (@persona.param(param_id) * persona_mult)
  677. end
  678. return value.to_i
  679. end
  680.  
  681. alias persona_xparam xparam
  682. def xparam(xparam_id)
  683. # get the value of the actor's x_parameter
  684. value = persona_xparam(xparam_id)
  685. if !persona? && !@persona.nil?
  686. # get the actor's and persona's multiplier and add both of their x_parameters
  687. # with their respective multiplier
  688. user_mult = USER_PARAM_MULTIPLIER.is_a?(Array) ? USER_XPARAM_MULTIPLIER[xparam_id] : USER_XPARAM_MULTIPLIER
  689. persona_mult = PERSONA_PARAM_MULTIPLIER.is_a?(Array) ? PERSONA_XPARAM_MULTIPLIER[xparam_id] : PERSONA_PARAM_MULTIPLIER
  690. value = (value * user_mult) + (@persona.xparam(xparam_id) * persona_mult)
  691. end
  692. return value
  693. end
  694.  
  695. alias persona_sparam sparam
  696. def sparam(sparam_id)
  697. # get the value of the actor's s_parameter
  698. value = persona_sparam(sparam_id)
  699. if !persona? && !@persona.nil?
  700. # get the actor's and persona's multiplier and add both of their s_parameters
  701. # with their respective multiplier
  702. user_mult = USER_PARAM_MULTIPLIER.is_a?(Array) ? USER_SPARAM_MULTIPLIER[sparam_id] : USER_SPARAM_MULTIPLIER
  703. persona_mult = PERSONA_PARAM_MULTIPLIER.is_a?(Array) ? PERSONA_SPARAM_MULTIPLIER[sparam_id] : PERSONA_SPARAM_MULTIPLIER
  704. value = (value * user_mult) + (@persona.sparam(sparam_id) * persona_mult)
  705. end
  706. return value
  707. end
  708.  
  709. def only_persona?
  710. return !only_persona.nil?
  711. end
  712.  
  713. def can_equip_persona(persona)
  714. persona.min_player_level <= @level && $game_party.persona_available(persona)
  715. end
  716.  
  717. alias persona_ge gain_exp
  718. def gain_exp(exp)
  719. persona_ge(exp)
  720. if !persona? && !@persona.nil?
  721. @persona.gain_exp(exp)
  722. end
  723. end
  724.  
  725. alias persona_fer final_exp_rate
  726. def final_exp_rate
  727. return persona_fer if !persona?
  728. return exr * Persona::PERSONA_EXP_GAIN_MULTIPLIER
  729. end
  730.  
  731. alias persona_i index
  732. def index
  733. return persona_i if !persona?
  734. # return persona's index from user's personas list
  735. user = $game_party.menu_actor
  736. return $game_party.actors_personas(user.id).index(self)
  737. end
  738.  
  739. def next_skill
  740. # return the next (closest in level) skill that the actor will learn
  741. self.class.learnings.select{ |learning| learning.level > @level}.min_by{ |learning| learning.level }
  742. end
  743.  
  744. def next_skills
  745. # return all the skills that the actor will learn
  746. self.class.learnings.select{ |learning| learning.level > @level }
  747. end
  748.  
  749. def on_battle_start
  750. super
  751. # reset flag on battle start
  752. @changed_persona = false
  753. end
  754.  
  755. def on_turn_end
  756. super
  757. # reset flag on turn end
  758. @changed_persona = false
  759. end
  760. end
  761.  
  762. class Game_Party < Game_Unit
  763. alias persona_init initialize
  764. def initialize
  765. @personas = []
  766. @menu_persona_id = 0
  767. persona_init
  768. end
  769.  
  770. def personas
  771. # returns party's personas
  772. @personas.collect{ |id| $game_personas[id] }
  773. end
  774.  
  775. alias persona_sbt setup_battle_test
  776. def setup_battle_test
  777. persona_sbt
  778. setup_test_battle_personas
  779. end
  780.  
  781. def battle_personas
  782. members.reject{|m| m.persona.nil?}.collect{|m| m.persona}
  783. end
  784.  
  785. def persona_in_party(persona_name)
  786. return !personas.find{|p| p.name == persona_name}.nil?
  787. end
  788.  
  789. def persona_equipped_by(actor_id, persona_name)
  790. actor = members.find{|m| m.id == actor_id}
  791. return false if actor.nil?
  792. return false if actor.persona.nil?
  793. return actor.persona.name == persona_name
  794. end
  795.  
  796. def persona_equipped(persona_name)
  797. persona = personas.find{|p| p.name == persona_name}
  798. return persona_available(persona)
  799. end
  800.  
  801. def setup_test_battle_personas
  802. $data_system.test_battlers.each do |battler|
  803. # get battletest persona of each battle test actor and equip them
  804. actor = $game_actors[battler.actor_id]
  805. btest_persona = $data_actors[battler.actor_id].battletest_persona
  806. if btest_persona != 0
  807. actor.change_persona($game_actors[btest_persona])
  808. end
  809. end
  810. end
  811.  
  812. def add_persona(persona_id)
  813. # inform user (script user) about the mistake just in case
  814. if $game_personas[persona_id].nil?
  815. msgbox("There was an attempt to add a persona with an invalid ID (ID=#{persona_id})")
  816. end
  817.  
  818. @personas.push(persona_id) if !@personas.include?(persona_id) && !$game_personas[persona_id].nil?
  819. # auto equip new persona if there is a member that uses only one persona
  820. user = members.find{|m| m.only_persona == persona_id}
  821. user.change_persona($game_personas[persona_id]) if !user.nil?
  822.  
  823. $game_player.refresh
  824. $game_map.need_refresh = true
  825. end
  826.  
  827. def remove_persona(persona_id)
  828. # unequip persona
  829. user = members.find{|m| !m.persona.nil? && m.persona.id == persona_id}
  830. user.remove_persona if !user.nil?
  831.  
  832. # remove persona from party
  833. @personas.delete(persona_id)
  834. $game_player.refresh
  835. $game_map.need_refresh = true
  836. end
  837.  
  838. def actors_personas(actor_id)
  839. # get the of the personas that belong to the actor
  840. ids = @personas.select{ |id| $game_personas[id].users.include?(actor_id) }
  841. # if the party has no personas that belong to the actor an empty list is returned
  842. return ids.collect{ |id| $game_personas[id] }
  843. end
  844.  
  845. def persona_available(persona)
  846. # returns if true if persona is not currently equipped by any member of the party
  847. members.inject(true){|available, m| available && m.persona != persona}
  848. end
  849.  
  850. def menu_persona
  851. $game_personas[@menu_persona_id] || menu_personas[0]
  852. end
  853.  
  854. def menu_persona=(persona)
  855. @menu_persona_id = persona.id
  856. end
  857.  
  858. def menu_personas
  859. # returns personas currently being shown in menu
  860. actors_personas(menu_actor.id)
  861. end
  862.  
  863. def menu_persona_next
  864. # calculate the index of the next persona
  865. index = menu_personas.index(menu_persona) || -1
  866. # if next index is higher than the size of menu_personas, it rounds it down
  867. # to the start
  868. index = (index + 1) % menu_personas.size
  869. self.menu_persona = actors_personas(menu_actor.id)[index]
  870. end
  871.  
  872. def menu_persona_prev
  873. # calculate the index of the previous persona
  874. index = menu_personas.index(menu_persona) || 1
  875. # if previous index is lower than 0, it basically rounds it back to the end
  876. index = (index + menu_personas.size - 1) % menu_personas.size
  877. self.menu_persona = actors_personas(menu_actor.id)[index]
  878. end
  879. end
  880.  
  881. class Game_Personas
  882. def initialize
  883. @data = []
  884. end
  885.  
  886. def [](actor_id)
  887. return nil if !$data_actors[actor_id]
  888. return nil if !$data_actors[actor_id].persona?
  889. @data[actor_id] ||= Game_Actor.new(actor_id)
  890. end
  891. end
  892.  
  893. class Window_ActorCommand < Window_Command
  894. alias persona_mcl make_command_list
  895. def make_command_list
  896. persona_mcl
  897. return unless @actor
  898. add_persona_command
  899. add_persona_skills_command if !Persona::UNIFIED_SKILLS
  900. end
  901.  
  902. def add_persona_command
  903. name = Persona::PERSONA_MENU_NAME
  904. ext = nil
  905. command = { :name=>name,
  906. :symbol=>:persona,
  907. :enabled=>@actor.can_change_persona,
  908. :ext=>ext}
  909. index = Persona::PERSONA_BATTLE_COMMAND_INDEX - 1
  910. index = [[0, index].max, @list.length].min
  911. @list.insert(index, command)
  912. end
  913.  
  914. def add_persona_skills_command
  915. return if @actor.persona.nil?
  916. index = Persona::PERSONA_SKILLS_COMMAND_INDEX
  917. @actor.persona_added_skill_types.sort.each do |stype_id|
  918. name = "#{Persona::PERSONA_MENU_NAME} #{$data_system.skill_types[stype_id]}"
  919. ext = stype_id
  920. command = { :name=>name,
  921. :symbol=>:persona_skills,
  922. :enabled=>true,
  923. :ext=>ext}
  924. index = [[0, index].max, @list.length].min
  925. @list.insert(index, command)
  926. index += 1
  927. end
  928. end
  929.  
  930. def refresh_persona_change
  931. setup(@actor)
  932. refresh
  933. end
  934. end
  935.  
  936. class Window_BattlePersonas < Window_Command
  937. def initialize(actor)
  938. @actor = actor
  939. @personas = $game_party.actors_personas(@actor.id)
  940. super(0, 0)
  941. select_last
  942. end
  943.  
  944. def actor=(actor)
  945. return if @actor == actor
  946. @actor = actor
  947. @personas = $game_party.actors_personas(@actor.id)
  948. refresh
  949. select_last
  950. end
  951.  
  952. def refresh
  953. contents.clear
  954. draw_all_items
  955. end
  956.  
  957. def window_width
  958. Graphics.width
  959. end
  960.  
  961. def window_height
  962. Graphics.height / 4
  963. end
  964.  
  965. def item_width
  966. (width - standard_padding * 2 + spacing) / col_max - spacing
  967. end
  968.  
  969. def col_max
  970. 2
  971. end
  972.  
  973. def item_height
  974. line_height
  975. end
  976.  
  977. def visible_line_number
  978. 4
  979. end
  980.  
  981. def item_max
  982. @personas.size
  983. end
  984.  
  985. def process_handling
  986. return unless open? && active
  987. return process_equip if equip_enabled? && Input.trigger?(:C)
  988. return process_cancel if cancel_enabled? && Input.trigger?(:B)
  989. end
  990.  
  991. def item
  992. @personas && index >= 0 ? @personas[index] : nil
  993. end
  994.  
  995. def enable?(persona)
  996. @actor && @actor.persona_change_ok?(persona)
  997. end
  998.  
  999. def current_item_enabled?
  1000. enable?($game_party.actors_personas(@actor.id)[index])
  1001. end
  1002.  
  1003. def process_equip
  1004. if current_item_enabled?
  1005. Sound.play_equip
  1006. Input.update
  1007. call_equip_handler
  1008. else
  1009. Sound.play_buzzer
  1010. end
  1011. end
  1012.  
  1013. def call_equip_handler
  1014. call_handler(:ok)
  1015. end
  1016. def equip_enabled?
  1017. handle?(:ok)
  1018. end
  1019.  
  1020. def draw_item_background(index)
  1021. equiped_persona_index = @personas.index(@actor.persona)
  1022. if index == equiped_persona_index
  1023. color = pending_color
  1024. color.alpha = 100
  1025. contents.fill_rect(item_rect(index), color)
  1026. end
  1027. end
  1028.  
  1029. def draw_persona_name_level(persona, rect, enabled)
  1030. change_color(system_color, enabled)
  1031. draw_text(rect, Vocab::level_a)
  1032. x = rect.x + text_size(Vocab::level_a).width
  1033. y = rect.y
  1034. txt = "#{persona.level} #{persona.name}"
  1035. change_color(normal_color, enabled)
  1036. draw_text(x, y, rect.width, rect.height, txt)
  1037. end
  1038.  
  1039. def draw_item(index)
  1040. persona = @personas[index]
  1041. rect = item_rect(index)
  1042. enabled = enable?(persona)
  1043. draw_item_background(index)
  1044. draw_persona_name_level(persona, rect, enabled)
  1045. end
  1046.  
  1047. def process_ok
  1048. super
  1049. persona = @personas[index]
  1050. $game_party.menu_persona = persona
  1051. end
  1052.  
  1053. def select_last
  1054. if $game_party.menu_persona.nil?
  1055. select(0)
  1056. else
  1057. select($game_party.menu_persona.index || 0)
  1058. end
  1059. end
  1060.  
  1061. def pending_index=(index)
  1062. last_pending_index = @pending_index
  1063. @pending_index = index
  1064. redraw_item(@pending_index)
  1065. redraw_item(last_pending_index)
  1066. end
  1067. end
  1068.  
  1069. class Window_BattleSkill < Window_SkillList
  1070. def draw_item_name(item, x, y, enabled = true, width = 172)
  1071. return unless item
  1072. draw_icon(item.icon_index, x, y, enabled)
  1073. if !@actor.persona_skills.index(item).nil?
  1074. change_color(Persona::PERSONA_SKILLS_COLOR, enabled)
  1075. else
  1076. change_color(normal_color, enabled)
  1077. end
  1078. draw_text(x + 24, y, width, line_height, item.name)
  1079. end
  1080. end
  1081.  
  1082. class Window_Keys < Window_Base
  1083. include Persona
  1084. def initialize
  1085. width = 200
  1086. height = line_height
  1087. super(Graphics.width - width, Graphics.height - height, width, height)
  1088. determine_window_size
  1089. draw_content
  1090. self.visible = false
  1091. end
  1092.  
  1093. def determine_window_size
  1094. # determines window's size according to the size of the button images
  1095. @select_button = Cache.persona_file(SELECT_PERSONA_BUTTON_IMG_NAME)
  1096. @equip_button = Cache.persona_file(EQUIP_PERSONA_BUTTON_IMG_NAME)
  1097. # largest height and width between the two button images
  1098. height = [@select_button.height, @equip_button.height].max
  1099. width = [@select_button.width, @equip_button.width].max
  1100. # increase width by largest width between two texts
  1101. width += [text_size(SELECT_PERSONA_TEXT).width, text_size(EQUIP_PERSONA_TEXT).width].max
  1102.  
  1103. # max width of window is half the width of the game window so that it doesn't
  1104. # overlap with the personas window
  1105. self.width = [width + standard_padding * 2, Graphics.width / 2].min
  1106. self.height = height * 2 + line_height + standard_padding
  1107.  
  1108. self.x = Graphics.width - self.width
  1109. self.y = Graphics.height - self.height
  1110.  
  1111. create_contents
  1112. end
  1113.  
  1114. def draw_content
  1115. contents.clear
  1116.  
  1117. # draw top button (select)
  1118. x = @select_button.width
  1119. txt_height = text_size(SELECT_PERSONA_TEXT).height
  1120. btn_height = @select_button.height
  1121. y = [txt_height, btn_height].max / 2
  1122. contents.blt(0, y - btn_height / 2, @select_button, @select_button.rect)
  1123. draw_text(x, y - txt_height/2, self.width - x - standard_padding, line_height, SELECT_PERSONA_TEXT)
  1124.  
  1125. # draw bottom button (equip)
  1126. x = @select_button.width
  1127. txt_height = text_size(EQUIP_PERSONA_TEXT).height
  1128. btn_height = @equip_button.height
  1129. y = contents.height / 2 + [txt_height, btn_height].max / 2
  1130. contents.blt(0, y - btn_height / 2, @equip_button, @equip_button.rect)
  1131. draw_text(x, y - txt_height / 2, self.width - x - standard_padding, line_height, EQUIP_PERSONA_TEXT)
  1132. end
  1133. end
  1134.  
  1135. class Window_MenuCommand < Window_Command
  1136. alias persona_mcl make_command_list
  1137. def make_command_list
  1138. persona_mcl
  1139. add_persona_command
  1140. end
  1141.  
  1142. def add_persona_command
  1143. # add persona command to main menu
  1144. name = Persona::PERSONA_MENU_NAME
  1145. ext = nil
  1146. command = { :name=>name,
  1147. :symbol=>:persona,
  1148. :enabled=>main_commands_enabled,
  1149. :ext=>ext}
  1150. index = Persona::PERSONA_MENU_COMMAND_INDEX - 1
  1151. index = [index, @list.length].min
  1152. @list.insert(index, command)
  1153. end
  1154. end
  1155.  
  1156. class Window_MenuStatus < Window_Selectable
  1157. def ok_enabled?
  1158. actor = $game_party.members[index]
  1159. # can't view persona's status for actor that can use only one persona and
  1160. # that persona is not equipped
  1161. return false if actor.only_persona? && actor.persona.nil?
  1162. handle?(:ok)
  1163. end
  1164. end
  1165.  
  1166. class Window_Personas < Window_Command
  1167. include Persona
  1168.  
  1169. def initialize(actor)
  1170. @actor = actor
  1171. @personas = $game_party.actors_personas(@actor.id)
  1172. super(0, 0)
  1173. self.visible = false
  1174. select_last
  1175. end
  1176.  
  1177. def actor=(actor)
  1178. return if @actor == actor
  1179. @actor = actor
  1180. @personas = $game_party.actors_personas(@actor.id)
  1181. refresh
  1182. select_last
  1183. end
  1184.  
  1185. def personas
  1186. @personas
  1187. end
  1188.  
  1189. def window_width
  1190. Graphics.width / 2
  1191. end
  1192.  
  1193. def window_height
  1194. Graphics.height
  1195. end
  1196.  
  1197. def item_height
  1198. (height - standard_padding * 2) / visible_line_number
  1199. end
  1200.  
  1201. def visible_line_number
  1202. 4
  1203. end
  1204.  
  1205. def item_max
  1206. @personas.size
  1207. end
  1208.  
  1209. def current_persona
  1210. @personas[index]
  1211. end
  1212.  
  1213. def process_handling
  1214. return unless open? && active
  1215. return process_equip if equip_enabled? && Input.trigger?(EQUIP_PERSONA_KEY)
  1216. super
  1217. end
  1218.  
  1219. def process_equip
  1220. if persona_equippable?
  1221. Sound.play_equip
  1222. Input.update
  1223. call_equip_handler
  1224. else
  1225. Sound.play_buzzer
  1226. end
  1227. end
  1228.  
  1229. def call_equip_handler
  1230. call_handler(:equip)
  1231. end
  1232.  
  1233. def equip_enabled?
  1234. handle?(:equip)
  1235. end
  1236.  
  1237. def refresh
  1238. super
  1239. contents.clear
  1240. draw_all_items
  1241. end
  1242.  
  1243. def draw_all_items
  1244. draw_no_personas_msg if @personas.empty?
  1245. super
  1246. end
  1247.  
  1248. def draw_no_personas_msg
  1249. draw_text(0, 0, width, line_height, NO_PERSONAS_MSG)
  1250. end
  1251.  
  1252. def draw_item(index)
  1253. persona = @personas[index]
  1254.  
  1255. enabled = @actor.can_equip_persona(persona)
  1256. rect = item_rect(index)
  1257. draw_item_background(index)
  1258. draw_actor_face(persona, rect.x + 1, rect.y + 1, enabled)
  1259. draw_actor_simple_status(persona, rect.x + 108, rect.y, enabled)
  1260. end
  1261.  
  1262. def draw_actor_simple_status(actor, x, y, enabled)
  1263. change_color(normal_color, enabled)
  1264. draw_actor_name(actor, x, y)
  1265. draw_actor_class(actor, x, y + line_height)
  1266. draw_actor_level(actor, x, y + line_height * 2)
  1267. change_color(normal_color)
  1268. end
  1269.  
  1270. def draw_item_background(index)
  1271. equiped_persona_index = @personas.index(@actor.persona)
  1272. if index == equiped_persona_index
  1273. color = pending_color
  1274. color.alpha = 100
  1275. contents.fill_rect(item_rect(index), color)
  1276. end
  1277. end
  1278.  
  1279. def persona_equippable?
  1280. persona = @personas[index]
  1281. return @actor.can_equip_persona(persona)
  1282. end
  1283.  
  1284. def process_ok
  1285. Sound.play_ok
  1286. Input.update
  1287. deactivate
  1288.  
  1289. persona = @personas[index]
  1290. $game_party.menu_persona = persona
  1291. call_ok_handler
  1292. end
  1293.  
  1294. def current_item_enabled?
  1295. persona = @personas[index]
  1296. enabled = $game_party.persona_available(persona) || @actor.persona == persona
  1297. return enabled
  1298. end
  1299.  
  1300. def select_last
  1301. if @personas.nil? || $game_party.menu_persona.nil?
  1302. select(-1)
  1303. else
  1304. select($game_party.menu_persona.index || 0)
  1305. end
  1306. end
  1307.  
  1308. def pending_index=(index)
  1309. last_pending_index = @pending_index
  1310. @pending_index = index
  1311. redraw_item(@pending_index)
  1312. redraw_item(last_pending_index)
  1313. end
  1314. end
  1315.  
  1316. class Window_PersonaStatus < Window_Command
  1317. include Persona
  1318.  
  1319. def initialize(persona)
  1320. @persona = persona
  1321. super(0, 0)
  1322. self.visible = false
  1323. select_last
  1324. end
  1325.  
  1326. def window_width
  1327. Graphics.width
  1328. end
  1329.  
  1330. def window_height
  1331. Graphics.height
  1332. end
  1333.  
  1334. def persona
  1335. @persona
  1336. end
  1337.  
  1338. def persona=(persona)
  1339. return if @persona == persona
  1340. @persona = persona
  1341. refresh
  1342. end
  1343.  
  1344. def process_handling
  1345. return unless open? && active
  1346. return process_equip if equip_enabled? && Input.trigger?(EQUIP_PERSONA_KEY)
  1347. return process_cancel if cancel_enabled? && Input.trigger?(:B)
  1348. super
  1349. end
  1350.  
  1351. def process_equip
  1352. if persona_equippable?
  1353. Sound.play_equip
  1354. Input.update
  1355. call_equip_handler
  1356. else
  1357. Sound.play_buzzer
  1358. end
  1359. end
  1360.  
  1361. def persona_equippable?
  1362. return $game_party.menu_actor.can_equip_persona(@persona)
  1363. end
  1364.  
  1365. def call_equip_handler
  1366. call_handler(:equip)
  1367. end
  1368.  
  1369. def equip_enabled?
  1370. handle?(:equip)
  1371. end
  1372.  
  1373. def refresh
  1374. contents.clear
  1375. draw_everything if !@persona.nil?
  1376. end
  1377.  
  1378. def draw_everything
  1379. draw_block1 (line_height * 0)
  1380. draw_horz_line(line_height * 1)
  1381. draw_block2 (line_height * 2)
  1382. draw_horz_line(line_height * 6)
  1383. draw_block3 (line_height * 7)
  1384. draw_horz_line(line_height * 13)
  1385. draw_block4 (line_height * 14)
  1386. end
  1387.  
  1388. def draw_block1(y)
  1389. draw_actor_name(@persona, 4, y)
  1390. draw_actor_class(@persona, 128, y)
  1391. draw_actor_nickname(@persona, 288, y)
  1392. end
  1393.  
  1394. def draw_block2(y)
  1395. draw_actor_face(@persona, 8, y)
  1396. draw_basic_info(136, y)
  1397. draw_exp_info(136, y)
  1398. draw_next_skill(136, y + line_height * 3)
  1399. end
  1400.  
  1401. def draw_block3(y)
  1402. draw_parameters(10, y)
  1403. draw_skills(100, y)
  1404. end
  1405.  
  1406. def draw_block4(y)
  1407. draw_ele_rates(30, y)
  1408. end
  1409.  
  1410. def draw_horz_line(y)
  1411. line_y = y + line_height / 2 - 1
  1412. contents.fill_rect(0, line_y, contents_width, 2, line_color)
  1413. end
  1414.  
  1415. def line_color
  1416. color = normal_color
  1417. color.alpha = 48
  1418. color
  1419. end
  1420.  
  1421. def draw_basic_info(x, y)
  1422. draw_actor_level(@persona, x, y + line_height * 0)
  1423. draw_actor_icons(@persona, x, y + line_height * 1)
  1424. end
  1425.  
  1426. def draw_parameters(x, y)
  1427. 6.times {|i| draw_actor_param(@persona, x, y + line_height * i, i + 2) }
  1428. end
  1429.  
  1430. def draw_actor_param(actor, x, y, param_id)
  1431. change_color(system_color)
  1432. draw_text(x, y, 120, line_height, Vocab::param(param_id))
  1433. change_color(normal_color)
  1434. draw_text(x + 30, y, 36, line_height, actor.param(param_id), 2)
  1435. end
  1436.  
  1437. def draw_exp_info(x, y)
  1438. s1 = @persona.max_level? ? "-------" : @persona.exp
  1439. s2 = @persona.max_level? ? "-------" : @persona.next_level_exp - @persona.exp
  1440. s_next = sprintf(Vocab::ExpNext, Vocab::level)
  1441. change_color(system_color)
  1442. draw_text(x, y + line_height * 1, 180, line_height, Vocab::ExpTotal)
  1443. draw_text(x, y + line_height * 2, 180, line_height, s_next)
  1444. change_color(normal_color)
  1445. draw_text(x, y + line_height * 1, 180, line_height, s1, 2)
  1446. draw_text(x, y + line_height * 2, 180, line_height, s2, 2)
  1447. end
  1448.  
  1449. def draw_next_skill(x, y)
  1450. next_skill = @persona.next_skill
  1451. return if next_skill.nil?
  1452. s_next = sprintf("Next %s at ", Vocab::skill.downcase[0...-1])
  1453. change_color(system_color)
  1454. draw_text(x, y, 180, line_height, s_next)
  1455. x += text_size(s_next).width
  1456.  
  1457. change_color(system_color)
  1458. draw_text(x, y, 180, line_height, Vocab::level_a)
  1459. x += text_size(Vocab::level_a).width
  1460.  
  1461. change_color(normal_color)
  1462. draw_text(x, y, 180, line_height, next_skill.level.to_s + ": ")
  1463. x += text_size(next_skill.level.to_s + ": ").width
  1464.  
  1465. change_color(normal_color)
  1466. skill_name = $data_skills[next_skill.skill_id].name
  1467. draw_text(x, y, 180, line_height, skill_name)
  1468. end
  1469.  
  1470. def draw_skills(x, y)
  1471. col_width = ((self.width - x) / 3).to_i
  1472. cols_max_x = [0, 0] # first and second cols only needed
  1473. @persona.skills.each_with_index do |item, i|
  1474. col = i.div(6)
  1475. offset_x = col_width * col
  1476. offset_y = line_height * i.divmod(6)[1]
  1477. draw_item_name(item, x + offset_x, y + offset_y, true, col_width - 24)
  1478. end
  1479. next_skills_i = @persona.skills.length
  1480. @persona.next_skills.each_with_index do |item, i|
  1481. i += next_skills_i
  1482. offset_x = 150 * (i/6).to_i
  1483. offset_y = line_height * i.divmod(6)[1]
  1484. draw_text(x + offset_x, y + offset_y, col_width, line_height, "-------")
  1485. end
  1486. end
  1487.  
  1488. def draw_ele_rates(x, y)
  1489. icons = PERSONA_ELE_ICON_INDEXES
  1490. 10.times do |i|
  1491. offset_x = i * (24 + 24) # icon width + space between them
  1492. new_x = x + offset_x
  1493. draw_icon(icons[i], new_x, y)
  1494. if @persona.element_rate(i+1) == 1.0
  1495. draw_normal_ele_icon(new_x, y)
  1496. elsif @persona.element_rate(i+1) > 1.0
  1497. draw_strong_ele_icon(new_x, y)
  1498. elsif @persona.element_rate(i+1) < 1.0
  1499. draw_weak_ele_icon(new_x, y)
  1500. end
  1501. end
  1502. end
  1503.  
  1504. def draw_normal_ele_icon(x, y)
  1505. if PERSONA_NORMAL_ELE_ICON == -1
  1506. draw_text(x, y + line_height, 24, line_height, "-", 1)
  1507. else
  1508. draw_icon(PERSONA_NORMAL_ELE_ICON, x, y + line_height)
  1509. end
  1510. end
  1511.  
  1512. def draw_strong_ele_icon(x, y)
  1513. if PERSONA_STRONG_ELE_ICON == -1
  1514. draw_text(x, y + line_height, 24, line_height, "Str", 1)
  1515. else
  1516. draw_icon(PERSONA_STRONG_ELE_ICON, x, y + line_height)
  1517. end
  1518. end
  1519.  
  1520. def draw_weak_ele_icon(x, y)
  1521. if PERSONA_WEAK_ELE_ICON == -1
  1522. draw_text(x, y + line_height, 24, line_height, "Wk", 1)
  1523. else
  1524. draw_icon(PERSONA_WEAK_ELE_ICON, x, y + line_height)
  1525. end
  1526. end
  1527.  
  1528. def select_last
  1529. select(-1)
  1530. end
  1531. end
  1532.  
  1533. class Scene_Battle < Scene_Base
  1534. alias persona_cacw create_actor_command_window
  1535. def create_actor_command_window
  1536. persona_cacw
  1537. @actor_command_window.set_handler(:persona, method(:command_persona))
  1538. @actor_command_window.set_handler(:persona_skills, method(:persona_skills))
  1539. @actor_command_window.set_handler(:persona_magic, method(:persona_skills))
  1540. end
  1541.  
  1542. def persona_skills
  1543. @skill_window.actor = BattleManager.actor.persona if BattleManager.actor.persona
  1544. @skill_window.stype_id = @actor_command_window.current_ext
  1545. @skill_window.refresh
  1546. @skill_window.show.activate
  1547. end
  1548.  
  1549. def command_persona
  1550. @persona_window = Window_BattlePersonas.new(BattleManager.actor)
  1551. @persona_window.select_last
  1552. @persona_window.set_handler(:ok, method(:on_persona_ok))
  1553. @persona_window.set_handler(:cancel, method(:on_persona_cancel))
  1554. end
  1555.  
  1556. def on_persona_ok
  1557. persona = @persona_window.item
  1558. BattleManager.actor.change_persona(persona)
  1559. BattleManager.actor.refresh
  1560. @persona_window.hide
  1561. @actor_command_window.activate
  1562. @actor_command_window.refresh_persona_change
  1563. @status_window.refresh
  1564. end
  1565.  
  1566. def on_persona_cancel
  1567. @persona_window.hide
  1568. @actor_command_window.activate
  1569. end
  1570.  
  1571. alias persona_oec on_enemy_cancel
  1572. def on_enemy_cancel
  1573. persona_oec
  1574. case @actor_command_window.current_symbol
  1575. when :persona_skills
  1576. @skill_window.activate
  1577. end
  1578. end
  1579.  
  1580. alias persona_oac on_actor_cancel
  1581. def on_actor_cancel
  1582. persona_oac
  1583. case @actor_command_window.current_symbol
  1584. when :persona_skills
  1585. @skill_window.activate
  1586. end
  1587. end
  1588. end
  1589.  
  1590. class Scene_Menu < Scene_MenuBase
  1591. include Persona
  1592.  
  1593. alias persona_ccw create_command_window
  1594. def create_command_window
  1595. persona_ccw
  1596. @command_window.set_handler(:persona, method(:command_persona))
  1597. end
  1598.  
  1599. def command_persona
  1600. @status_window.select_last
  1601. @status_window.activate
  1602. @status_window.set_handler(:ok, method(:on_persona_user_ok))
  1603. @status_window.set_handler(:cancel, method(:on_personal_cancel))
  1604. end
  1605.  
  1606. def on_persona_user_ok
  1607. SceneManager.call(Scene_Personas)
  1608. end
  1609. end
  1610.  
  1611. class Scene_Personas < Scene_Base
  1612. def start
  1613. super
  1614. create_background
  1615. @actor = $game_party.menu_actor
  1616. @persona = @actor.persona
  1617. create_personas_window
  1618. create_buttons_window
  1619. create_status_window
  1620. on_actor_change
  1621. end
  1622.  
  1623. def terminate
  1624. super
  1625. dispose_background
  1626. end
  1627.  
  1628. def create_background
  1629. @background_sprite = Sprite.new
  1630. @background_sprite.bitmap = SceneManager.background_bitmap
  1631. @background_sprite.color.set(16, 16, 16, 128)
  1632. end
  1633.  
  1634. def dispose_background
  1635. @background_sprite.dispose
  1636. end
  1637.  
  1638. def create_buttons_window
  1639. @buttons_window = Window_Keys.new
  1640. @buttons_window.open
  1641. end
  1642.  
  1643. def create_personas_window
  1644. @personas_window = Window_Personas.new(@actor)
  1645. @personas_window.select_last
  1646. @personas_window.set_handler(:ok, method(:on_persona_ok))
  1647. @personas_window.set_handler(:cancel, method(:return_scene))
  1648. @personas_window.set_handler(:equip, method(:persona_equip))
  1649. @personas_window.set_handler(:pagedown, method(:next_actor))
  1650. @personas_window.set_handler(:pageup, method(:prev_actor))
  1651. @personas_window.open
  1652. end
  1653.  
  1654. def create_status_window
  1655. @status_window = Window_PersonaStatus.new($game_party.menu_persona)
  1656. @status_window.set_handler(:cancel, method(:close_status))
  1657. @status_window.set_handler(:equip, method(:persona_equip))
  1658. @status_window.set_handler(:pagedown, method(:next_persona))
  1659. @status_window.set_handler(:pageup, method(:prev_persona))
  1660. @status_window.open
  1661. end
  1662.  
  1663. def on_persona_ok
  1664. @status_window.persona = @personas_window.current_persona
  1665. @status_window.show.activate
  1666. @personas_window.deactivate
  1667. end
  1668.  
  1669. def persona_equip
  1670. # get previous persona index
  1671. prev_persona_index = @personas_window.personas.index(@actor.persona)
  1672. @actor.remove_persona
  1673. # redraw that item in window
  1674. @personas_window.redraw_item(prev_persona_index) if !prev_persona_index.nil?
  1675. #equip new persona
  1676. if @status_window.active
  1677. @actor.change_persona(@persona)
  1678. else
  1679. @actor.change_persona(@personas_window.current_persona)
  1680. end
  1681. #redrwa that item
  1682. index = @personas_window.personas.index(@actor.persona)
  1683. @personas_window.redraw_item(index)
  1684. end
  1685.  
  1686. def on_actor_change
  1687. if @actor.only_persona? && !@persona.nil?
  1688. # if current (new actor after next/prev_actor) uses only one persona
  1689. # and the persona is equipped, skip to status window (does not show
  1690. # all personas that can be equipped by specific actor as he can only
  1691. # equip one and it is auto-equipped when added to the party)
  1692. @personas_window.deactivate
  1693. @personas_window.hide
  1694. @buttons_window.hide
  1695. @status_window.persona = @persona
  1696. @status_window.show.activate
  1697. else
  1698. # else show list of personas current actor can equip
  1699. @status_window.deactivate
  1700. @status_window.hide
  1701. @buttons_window.show
  1702. @personas_window.actor = @actor
  1703. @personas_window.show.activate
  1704. end
  1705. end
  1706.  
  1707. def next_actor
  1708. new_actor = $game_party.menu_actor_next
  1709. if new_actor.only_persona? && new_actor.persona.nil?
  1710. # if next actor can equip only one persona and it is not equipped (not in
  1711. # the party) then stay in current actor
  1712. $game_party.menu_actor_prev
  1713. else
  1714. @actor = new_actor
  1715. @persona = @actor.persona
  1716. on_actor_change
  1717. end
  1718. end
  1719.  
  1720. def prev_actor
  1721. new_actor = $game_party.menu_actor_prev
  1722. if new_actor.only_persona? && new_actor.persona.nil?
  1723. # if pervious actor can equip only one persona and it is not equipped (not in
  1724. # the party) then stay in current actor
  1725. $game_party.menu_actor_next
  1726. else
  1727. @actor = new_actor
  1728. @persona = @actor.persona
  1729. on_actor_change
  1730. end
  1731. end
  1732.  
  1733. def next_persona
  1734. if @actor.only_persona?
  1735. # if current actor can equip only one persona go to next actor
  1736. next_actor
  1737. else
  1738. # else go to next persona
  1739. @persona = $game_party.menu_persona_next
  1740. @status_window.persona = @persona
  1741. @status_window.activate # pagedown handler deactivates window
  1742. end
  1743. end
  1744.  
  1745. def prev_persona
  1746. if @actor.only_persona?
  1747. # if current actor can equip only one persona go to previous actor
  1748. prev_actor
  1749. else
  1750. # else go to previous persona
  1751. @persona = $game_party.menu_persona_prev
  1752. @status_window.persona = @persona
  1753. @status_window.activate # pagedown handler deactivates window
  1754. end
  1755. end
  1756.  
  1757. def close_status
  1758. if @actor.only_persona?
  1759. # if current actor can equip only one persona return scene
  1760. SceneManager.return
  1761. return
  1762. else
  1763. # else just close the status window
  1764. @status_window.deactivate
  1765. @status_window.hide
  1766. @personas_window.activate
  1767. end
  1768. end
  1769. end
  1770.  
  1771. #-------------------------------------------------------------------------------
  1772. # ____ _ _ _ _ _____ _
  1773. # / ___|| | _(_) | | | ___|__ _ __ __ _ ___| |_
  1774. # \___ \| |/ / | | | | |_ / _ \| '__/ _` |/ _ \ __|
  1775. # ___) | <| | | | | _| (_) | | | (_| | __/ |_
  1776. # |____/|_|\_\_|_|_| |_| \___/|_| \__, |\___|\__|
  1777. # |___/
  1778. # __ __ _ _
  1779. # | \/ | ___ __| |_ _| | ___
  1780. # | |\/| |/ _ \ / _` | | | | |/ _ \
  1781. # | | | | (_) | (_| | |_| | | __/
  1782. # |_| |_|\___/ \__,_|\__,_|_|\___|
  1783. #
  1784. # Skill Forget Module
  1785. #-------------------------------------------------------------------------------
  1786. class RPG::Actor < RPG::BaseItem
  1787. def max_skills
  1788. # min rank required to fuse persona
  1789. note =~ /<Max skills: (\d+)>/ ? $1.to_i : Persona::DEFAULT_MAX_PERSONA_SKILLS
  1790. end
  1791. end
  1792.  
  1793. class Game_Actor < Game_Battler
  1794. attr_accessor :extra_skills
  1795. attr_reader :max_skills
  1796.  
  1797. alias persona_forget_sp setup_persona
  1798. def setup_persona
  1799. persona_forget_sp
  1800. @extra_skills = []
  1801. @max_skills = actor.max_skills
  1802. end
  1803.  
  1804. alias persona_forget_is init_skills
  1805. def init_skills
  1806. if actor.persona?
  1807. @skills = []
  1808. # reverse learning so that persona doesn't learn low level skills
  1809. self.class.learnings.reverse.each do |learning|
  1810. learn_skill(learning.skill_id) if learning.level <= @level
  1811. # is used instead of @max_skills because persona sestup is done
  1812. # after actor initialization
  1813. break if @skills.size >= actor.max_skills
  1814. end
  1815. else
  1816. persona_forget_is
  1817. end
  1818. end
  1819.  
  1820. def level_up
  1821. @level += 1
  1822. self.class.learnings.each do |learning|
  1823. if persona? && @skills.size >= @max_skills
  1824. @extra_skills.push(learning.skill_id) if learning.level == @level
  1825. else
  1826. learn_skill(learning.skill_id) if learning.level == @level
  1827. end
  1828. end
  1829. end
  1830.  
  1831. alias persona_forget_ce change_exp
  1832. def change_exp(exp, show)
  1833. persona_forget_ce(exp, show)
  1834. if @extra_skills.size > 0
  1835. $game_party.menu_persona = self
  1836. if !SceneManager.scene_is?(Scene_Battle)
  1837. SceneManager.call(Scene_ForgetSkill)
  1838. end
  1839. end
  1840. refresh
  1841. end
  1842.  
  1843. def replace_skill(old_skill, new_skill)
  1844. index = @skills.index(old_skill.id)
  1845. @skills[index] = new_skill.id
  1846. end
  1847. end
  1848.  
  1849. class Window_NewSkill < Window_Base
  1850. def initialize(x, y)
  1851. height = line_height * 2
  1852. super(x, y, 200, height)
  1853. self.openness = 0
  1854. end
  1855.  
  1856. def text=(txt)
  1857. contents.clear
  1858. self.width = text_size(txt).width + standard_padding * 2
  1859. create_contents
  1860. draw_text(0, 0, self.width - standard_padding, line_height, txt)
  1861. end
  1862. end
  1863.  
  1864. class Window_PersonaStatus < Window_Command
  1865. alias persona_forget_init initialize
  1866. def initialize(persona)
  1867. persona_forget_init(persona)
  1868. if !extra_skills.empty?
  1869. clear_command_list
  1870. make_command_list
  1871. end
  1872. select_last
  1873. end
  1874.  
  1875. def extra_skills
  1876. @persona ? @persona.extra_skills : []
  1877. end
  1878.  
  1879. def draw_skills(x, y)
  1880. col_width = ((self.width - x) / 3).to_i
  1881. cols_max_x = [0, 0] # first and second cols only needed
  1882. @persona.skills.each_with_index do |item, i|
  1883. col = i.div(6)
  1884. offset_x = col_width * col
  1885. offset_y = line_height * i.divmod(6)[1]
  1886. draw_item_name(item, x + offset_x, y + offset_y, true, col_width - 24)
  1887. end
  1888. next_skills_i = @persona.skills.length
  1889. @persona.next_skills.each_with_index do |item, i|
  1890. i += next_skills_i
  1891. break if i >= @persona.max_skills
  1892. offset_x = 150 * (i/6).to_i
  1893. offset_y = line_height * i.divmod(6)[1]
  1894. draw_text(x + offset_x, y + offset_y, col_width, line_height, "-------")
  1895. end
  1896. end
  1897.  
  1898. alias persona_forget_pcm process_cursor_move
  1899. def process_cursor_move
  1900. persona_forget_pcm if !extra_skills.empty?
  1901. end
  1902.  
  1903. alias persona_forget_ph process_handling
  1904. def process_handling
  1905. if !extra_skills.empty?
  1906. return unless open? && active
  1907. return process_forget if forget_enabled? && Input.trigger?(:C)
  1908. return process_cancel if cancel_enabled? && Input.trigger?(:B)
  1909. else
  1910. persona_forget_ph
  1911. end
  1912. end
  1913.  
  1914. def process_forget
  1915. Sound.play_equip
  1916. Input.update
  1917. call_forget_handler
  1918. end
  1919.  
  1920. def call_forget_handler
  1921. call_handler(:forget)
  1922. end
  1923.  
  1924. def forget_enabled?
  1925. handle?(:forget)
  1926. end
  1927.  
  1928. def item_width
  1929. ((self.width - 100)/3).to_i
  1930. end
  1931.  
  1932. def row_max
  1933. [(item_max + col_max - 1) / item_max, 1].max
  1934. end
  1935.  
  1936. def item_max
  1937. @persona ? @persona.max_skills : 1
  1938. end
  1939.  
  1940. def item_rect(index)
  1941. rect = Rect.new
  1942. rect.width = item_width
  1943. rect.height = item_height
  1944. rect.x = ((index/6).to_i * item_width) + 100
  1945. rect.y = (item_height * index.divmod(6)[1]) + line_height * 7
  1946. rect
  1947. end
  1948.  
  1949. def col_max
  1950. 3
  1951. end
  1952.  
  1953. def select_last
  1954. if extra_skills.empty?
  1955. select(-1)
  1956. else
  1957. select(0)
  1958. end
  1959. end
  1960.  
  1961. def cursor_down(wrap = false)
  1962. if col_max >= 2 && (index < item_max - 1 || (wrap && horizontal?))
  1963. select((index + 1) % item_max)
  1964. end
  1965. end
  1966.  
  1967. def cursor_up(wrap = false)
  1968. if col_max >= 2 && (index > 0 || (wrap && horizontal?))
  1969. select((index - 1 + item_max) % item_max)
  1970. end
  1971. end
  1972.  
  1973. def cursor_right(wrap = false)
  1974. new_index = [index + 6, item_max - 1].min
  1975. if wrap && index >= item_max - 1
  1976. new_index = 0
  1977. end
  1978. select(new_index)
  1979. end
  1980.  
  1981. def cursor_left(wrap = false)
  1982. new_index = [index - 6, 0].max
  1983. if wrap && index == 0
  1984. new_index = item_max - 1
  1985. end
  1986. select(new_index)
  1987. end
  1988. end
  1989.  
  1990. class Scene_ForgetSkill < Scene_Base
  1991. alias persona_forget_start start
  1992. def start
  1993. persona_forget_start
  1994. create_windows
  1995. create_background
  1996. end
  1997.  
  1998. def start_without_bg
  1999. create_windows
  2000. end
  2001.  
  2002. def create_windows
  2003. create_main_viewport
  2004. create_status_window
  2005. create_message_window
  2006. create_new_skill_window
  2007. end
  2008.  
  2009. def create_status_window
  2010. @status_window = Window_PersonaStatus.new($game_party.menu_persona)
  2011. @status_window.set_handler(:cancel, method(:cancel_forget))
  2012. @status_window.set_handler(:forget, method(:skill_forget))
  2013. @status_window.show.activate
  2014. end
  2015.  
  2016. def create_background
  2017. @background_sprite = Sprite.new
  2018. @background_sprite.bitmap = SceneManager.background_bitmap
  2019. @background_sprite.color.set(16, 16, 16, 128)
  2020. end
  2021.  
  2022. def terminate
  2023. super
  2024. dispose_background
  2025. end
  2026.  
  2027. def dispose_background
  2028. @background_sprite.dispose if @background_sprite
  2029. end
  2030.  
  2031. def post_start
  2032. super
  2033. show_message if $game_party.menu_persona.extra_skills.size > 0
  2034. end
  2035.  
  2036. def show_message
  2037. $game_message.add("#{@status_window.persona.name} can't learn any new skills!\nSelect a skill to forget")
  2038. wait_for_message
  2039. @status_window.activate
  2040. end
  2041.  
  2042. def create_new_skill_window
  2043. @new_skill_window = Window_NewSkill.new(150, 24 * 5)
  2044. @new_skill_window.open
  2045. skill_id = $game_party.menu_persona.extra_skills[0]
  2046. skill = $data_skills[skill_id]
  2047. txt = "New skill: " + skill.name
  2048. @new_skill_window.text= txt
  2049. end
  2050.  
  2051. def create_message_window
  2052. $game_message.clear
  2053. @message_window = Window_Message.new
  2054. @choice = 0
  2055. end
  2056.  
  2057. def wait_for_message
  2058. @status_window.deactivate
  2059. @message_window.activate
  2060. @message_window.update
  2061. update_basic while $game_message.visible
  2062. end
  2063.  
  2064. def cancel_forget
  2065. persona = @status_window.persona
  2066. skill = persona.skills[@status_window.index]
  2067. new_skill = $data_skills[persona.extra_skills[0]]
  2068.  
  2069. $game_message.add("Are you sure you don't want #{persona.name}\nto learn #{new_skill.name}?")
  2070. $game_message.choices.push("Yes")
  2071. $game_message.choices.push("No")
  2072. $game_message.choice_cancel_type = 2
  2073. $game_message.choice_proc = Proc.new {|n| @choice = n }
  2074. wait_for_message
  2075. index = @status_window.index
  2076. if @choice == 0
  2077. @status_window.activate
  2078. persona.extra_skills.delete_at(0)
  2079. @status_window.refresh
  2080. $game_message.add("#{persona.name} didn't learn #{new_skill.name}!")
  2081. wait_for_message
  2082. else
  2083. @status_window.activate
  2084. return
  2085. end
  2086. finish_new_skill
  2087. end
  2088.  
  2089. def skill_forget
  2090. persona = @status_window.persona
  2091. @status_window.deactivate
  2092. skill = persona.skills[@status_window.index]
  2093. new_skill = $data_skills[persona.extra_skills[0]]
  2094. $game_message.add("Are you sure you want #{persona.name} to forget\n#{skill.name} and learn #{new_skill.name}?")
  2095. $game_message.choices.push("Yes")
  2096. $game_message.choices.push("No")
  2097. $game_message.choice_cancel_type = 2
  2098. $game_message.choice_proc = Proc.new {|n| @choice = n }
  2099. wait_for_message
  2100. index = @status_window.index
  2101. if @choice == 0
  2102. persona.replace_skill(skill, new_skill)
  2103. persona.extra_skills.delete_at(0)
  2104. @status_window.refresh
  2105. $game_message.add("#{persona.name} forgot #{skill.name} and learned\n#{new_skill.name}!")
  2106. wait_for_message
  2107. else
  2108. @status_window.activate
  2109. return
  2110. end
  2111. finish_new_skill
  2112. end
  2113.  
  2114. def next_new_skill
  2115. skill_id = $game_party.menu_persona.extra_skills[0]
  2116. skill = $data_skills[skill_id]
  2117. txt = "New skill: " + skill.name
  2118. @new_skill_window.text= txt
  2119. show_message
  2120. end
  2121.  
  2122. def finish_new_skill
  2123. if !$game_party.menu_persona.extra_skills.empty?
  2124. next_new_skill
  2125. else
  2126. @status_window.activate
  2127. @status_window.close
  2128. @new_skill_window.close
  2129. update_basic while @new_skill_window.openness > 0
  2130. SceneManager.return
  2131. end
  2132. end
  2133. end
  2134.  
  2135. #-------------------------------------------------------------------------------
  2136. # _ __ __ _ _
  2137. # / \ _ __ ___ __ _ _ __ __ _ | \/ | ___ __| |_ _| | ___
  2138. # / _ \ | '__/ __/ _` | '_ \ / _` | | |\/| |/ _ \ / _` | | | | |/ _ \
  2139. # / ___ \| | | (_| (_| | | | | (_| | | | | | (_) | (_| | |_| | | __/
  2140. # /_/ \_\_| \___\__,_|_| |_|\__,_| |_| |_|\___/ \__,_|\__,_|_|\___|
  2141. #
  2142. # Arcana Module
  2143. #-------------------------------------------------------------------------------
  2144. class RPG::Actor < RPG::BaseItem
  2145. def social_description
  2146. note =~ /<Social description: [\t]*([^\n\r]*)>/ ? $1 : ""
  2147. end
  2148.  
  2149. def min_arcana_rank
  2150. # min rank required to fuse persona
  2151. note =~ /<Arcana rank: (\d+)>/ ? $1.to_i : 0
  2152. end
  2153.  
  2154. def battletest_persona
  2155. # get persona to use for battletest
  2156. note =~ /<Battletest persona: (\d+)>/ ? $1.to_i : 0
  2157. end
  2158. end
  2159.  
  2160. class RPG::Class < RPG::BaseItem
  2161. def arcana?
  2162. note =~ /<Arcana>/ ? true : false
  2163. end
  2164.  
  2165. def rank_var_id
  2166. note =~ /<Rank variable: (\d+)>/ ? $1.to_i : nil
  2167. end
  2168.  
  2169. def max_rank
  2170. note =~ /<Max rank: (\d+)>/ ? $1.to_i : Persona::DEFAULT_MAX_RANK
  2171. end
  2172.  
  2173. def arcana_is?(arcana_name)
  2174. arcana_name == self.name
  2175. end
  2176.  
  2177. def social_target
  2178. note =~ /<Social target: [\t]*([^\n\r]*)>/ ? $1 : ""
  2179. end
  2180.  
  2181. def description
  2182. note =~ /<Description: [\t]*([^\n\r]*)>/ ? $1 : ""
  2183. end
  2184.  
  2185. def social_links
  2186. # gathers both actor ids and actor ids from variables and returns them
  2187. actors = social_links_actors
  2188. vars = []
  2189. social_links_variables.each{ |v| vars.push($game_variables[v]) if $game_variables[v] != -1 }
  2190. return (actors + vars).uniq
  2191. end
  2192.  
  2193. def social_links_actors
  2194. # return actor ids from tag
  2195. actors = /<Social links actors: (\d+(,[ ]?\d+)*)?>/.match(note)
  2196. return [] if actors.nil?
  2197. return actors[1].split(",").collect{ |i| i.to_i }
  2198. end
  2199.  
  2200. def social_links_variables
  2201. # return variable ids from tag
  2202. vars = /<Social links vars: (\d+(,[ ]?\d+)*)?>/.match(note)
  2203. return [] if vars.nil?
  2204. return vars[1].split(",").collect{ |i| i.to_i }
  2205. end
  2206. end
  2207.  
  2208. module Cache
  2209. def self.arcana(filename)
  2210. load_bitmap("Graphics/" + Persona::ARCANA_IMG_FOLDER, filename)
  2211. end
  2212.  
  2213. def self.persona_file(filename)
  2214. load_bitmap("Graphics/Persona/", filename)
  2215. end
  2216. end
  2217.  
  2218. class Game_Actor < Game_Battler
  2219. include Persona
  2220.  
  2221. attr_reader :social_description, :max_arcana_rank, :min_arcana_rank
  2222. alias persona_arcana_sp setup_persona
  2223. def setup_persona
  2224. persona_arcana_sp
  2225. @social_description = actor.social_description
  2226. @is_arcana = @is_persona ? self.class.arcana? : false
  2227. @max_arcana_rank = @is_persona ? self.class.max_rank : nil
  2228. @rank_var_id = self.class.rank_var_id
  2229. @min_arcana_rank = actor.min_arcana_rank
  2230. end
  2231.  
  2232. alias persona_arcana_cep can_equip_persona
  2233. def can_equip_persona(persona)
  2234. persona_arcana_cep(persona)
  2235. end
  2236.  
  2237. def arcana?
  2238. @is_arcana
  2239. end
  2240.  
  2241. def arcana_rank
  2242. $game_variables[@rank_var_id] if arcana?
  2243. end
  2244.  
  2245. def special_persona?
  2246. @is_special_persona
  2247. end
  2248. end
  2249.  
  2250. class Game_Player < Game_Character
  2251. include Persona
  2252. def arcana_rank_up(arcana_name)
  2253. # increases rank of arcana by one
  2254. arcana = $data_classes.find{ |c| !c.nil? && c.arcana? && c.name == arcana_name }
  2255. return if arcana.nil?
  2256. rank = $game_variables[arcana.rank_var_id]
  2257. rank += 1
  2258. $game_variables[arcana.rank_var_id] = [rank, 0].max
  2259. end
  2260.  
  2261. def arcana_rank_down(arcana_name)
  2262. # decreases rank of arcana by one
  2263. arcana = $data_classes.find{ |c| !c.nil? && c.arcana? && c.name == arcana_name }
  2264. return if arcana.nil?
  2265. rank = $game_variables[arcana.rank_var_id]
  2266. rank -= 1
  2267. $game_variables[arcana.rank_var_id] = [rank, 0].max
  2268. end
  2269.  
  2270. def arcana_rank_up_by(arcana_name, ranks_up)
  2271. ranks_up.times.do{ arcana_rank_up(arcana_name) }
  2272. end
  2273.  
  2274. def arcana_rank_down_by(arcana_name, ranks_down)
  2275. ranks_down.times.do{ arcana_rank_down(arcana_name) }
  2276. end
  2277.  
  2278. def available_arcanas
  2279. # returns arcanas which rank is higher than MIN_RANK
  2280. arcanas = $data_classes.select{ |c| !c.nil? && c.arcana? && !c.rank_var_id.nil? }
  2281. available_arcanas = arcanas.select{ |a| $game_variables[a.rank_var_id] >= MIN_RANK }
  2282. return available_arcanas
  2283. end
  2284. end
  2285.  
  2286. class Game_Variables
  2287. alias :arcana_rank :[]
  2288. def [](variable_id)
  2289. ret_val = arcana_rank(variable_id)
  2290.  
  2291. # get all arcanas that have a variable id for their rank
  2292. arcanas = $data_classes.select{ |c| !c.nil? && c.arcana? && !c.rank_var_id.nil? }
  2293. # get their variable id
  2294. ids = arcanas.collect{ |c| c.rank_var_id }
  2295.  
  2296. if ids.index(variable_id).nil?
  2297. # return value of variable if it is not an arcana's rank
  2298. return ret_val
  2299. else
  2300. # if id is one of arcanas' rank return its rank
  2301. # or if it is nil, return default value which is Persona::MIN_RANK - 1
  2302. @data[variable_id] || 0
  2303. end
  2304. end
  2305. end
  2306.  
  2307. class Window_ArcanaInfo < Window_Base
  2308. def initialize(arcana)
  2309. super(0, 0, window_width, window_height)
  2310. @selected_arcana = arcana
  2311. @arcana_y = 0
  2312. @info_x = 0
  2313. @info_y = 0
  2314. self.openness = 0
  2315. end
  2316.  
  2317. def window_width
  2318. Graphics.width
  2319. end
  2320.  
  2321. def window_height
  2322. Graphics.height * 0.35
  2323. end
  2324.  
  2325. def draw_arcana_rank
  2326. rank_str = " Rank #{$game_variables[@selected_arcana.rank_var_id]}"
  2327. w = text_size(rank_str).width
  2328. h = text_size(rank_str).height
  2329. draw_text(0, 0, w, h, rank_str)
  2330. @arcana_y += h
  2331. end
  2332.  
  2333. def draw_arcana
  2334. bitmap = Cache.arcana(@selected_arcana.name)
  2335. ratio_h = 1.0 - ((window_height - bitmap.height - @arcana_y - standard_padding*2).abs / bitmap.height.to_f)
  2336. ratio_h += (window_height > bitmap.height ? 1.0 : 0.0)
  2337. ratio_w = ratio_h
  2338. new_w = bitmap.width * ratio_w
  2339. new_h = (bitmap.height * ratio_h) - 2
  2340. new_rect = Rect.new(0, @arcana_y, new_w, new_h)
  2341. contents.stretch_blt(new_rect, bitmap, bitmap.rect)
  2342. bitmap.dispose
  2343.  
  2344. @info_x += new_w
  2345. end
  2346.  
  2347. def draw_arcana_name
  2348. if @selected_arcana.social_target.empty?
  2349. social_target = ""
  2350. else
  2351. social_target = @selected_arcana.social_target
  2352. end
  2353.  
  2354. text = " #{@selected_arcana.name} #{social_target}"
  2355. w = window_width
  2356. h = text_size(text).height
  2357. draw_text(@info_x, 0, w, h, text)
  2358.  
  2359. @info_y += h
  2360. end
  2361.  
  2362. def draw_arcana_info
  2363. text = @selected_arcana.description
  2364. return if text.empty?
  2365.  
  2366. words = text.split(" ")
  2367. line_num = 0
  2368.  
  2369. text_line = " " + words[0]
  2370. for i in 1..words.size
  2371. if i == words.size
  2372. w = window_width - @info_x
  2373. h = line_height
  2374. draw_text(@info_x, @info_y + line_num*h, w, h, text_line)
  2375. break
  2376. end
  2377.  
  2378. new_text = text_line + " " + words[i]
  2379. line_size = text_size(new_text)
  2380. if line_size.width + @info_x > window_width
  2381. w = line_size.width
  2382. h = line_height
  2383. draw_text(@info_x, @info_y + line_num*h, w, h, text_line)
  2384. line_num += 1
  2385. text_line = (" " + words[i])
  2386. else
  2387. text_line += (" " + words[i])
  2388. end
  2389. end
  2390. end
  2391.  
  2392. def refresh
  2393. contents.clear
  2394. return if @selected_arcana.nil?
  2395. draw_arcana_rank
  2396. draw_arcana
  2397. draw_arcana_name
  2398. draw_arcana_info
  2399. end
  2400.  
  2401. def draw_item_background(index)
  2402. if index == @pending_index
  2403. contents.fill_rect(item_rect(index), pending_color)
  2404. end
  2405. end
  2406. end
  2407.  
  2408. class Window_Arcanas < Window_Command
  2409. include Persona
  2410.  
  2411. def initialize
  2412. @arcanas = $game_player.available_arcanas
  2413. load_bitmaps
  2414. super(0, 0)
  2415. select_last
  2416. @selected_arcana = nil
  2417. self.openness = 0
  2418.  
  2419. end
  2420.  
  2421. def load_bitmaps
  2422. @progress_bar = Cache.persona_file(ARCANA_RANKS_BAR_IMG_NAME)
  2423. @subbar_empty = Cache.persona_file(ARCANA_PROGRESS_EMPTY_IMG_NAME)
  2424. @subbar_filled = Cache.persona_file(ARCANA_PROGRESS_IMG_NAME)
  2425. end
  2426.  
  2427. def dispose
  2428. super
  2429. dispose_bitmaps
  2430. end
  2431.  
  2432. def dispose_bitmaps
  2433. @progress_bar.dispose
  2434. @subbar_empty.dispose
  2435. @subbar_filled.dispose
  2436. end
  2437.  
  2438. def refresh
  2439. contents.clear
  2440. draw_all_items
  2441. end
  2442.  
  2443. def window_width
  2444. Graphics.width
  2445. end
  2446.  
  2447. def window_height
  2448. Graphics.height
  2449. end
  2450.  
  2451. def item_width
  2452. (width - standard_padding * 2 + spacing) / col_max - spacing
  2453. end
  2454.  
  2455. def item_height
  2456. (height - standard_padding * 2) / visible_line_number
  2457. end
  2458.  
  2459. def visible_line_number
  2460. 3
  2461. end
  2462.  
  2463. def item_max
  2464. @arcanas.size
  2465. end
  2466.  
  2467. def process_ok
  2468. call_show_rank_handler
  2469. end
  2470.  
  2471. def call_rank_handler
  2472. call_handler(:show_rank)
  2473. end
  2474. def rank_enabled?
  2475. handle?(:show_rank)
  2476. end
  2477.  
  2478. def draw_actor_simple_status(actor, x, y, enabled)
  2479. change_color(normal_color, enabled)
  2480. draw_actor_name(actor, x, y)
  2481. change_color(normal_color)
  2482. end
  2483.  
  2484. def draw_arcana(arcana, x, y)
  2485. bitmap = Cache.arcana(arcana.name)
  2486. ratio_h = 1 - ((item_height - bitmap.height).abs / bitmap.height.to_f)
  2487. ratio_h += (item_height > bitmap.height ? 1.0 : 0.0)
  2488. ratio_w = ratio_h
  2489. new_w = bitmap.width * ratio_w
  2490. new_h = (bitmap.height * ratio_h) - 2
  2491. new_rect = Rect.new(x, y, new_w, new_h)
  2492. contents.stretch_blt(new_rect, bitmap, bitmap.rect)
  2493. bitmap.dispose
  2494. end
  2495.  
  2496. def draw_rank_progress(x, y, index, width)
  2497. offset_x = width * index
  2498. height = @subbar_filled.height
  2499. rect = Rect.new(x + offset_x, y, width, height)
  2500. contents.stretch_blt(rect, @subbar_filled, @subbar_filled.rect)
  2501. end
  2502.  
  2503. def draw_rank_remaining(x, y, index, width)
  2504. offset_x = width * index
  2505. height = @subbar_empty.height
  2506. rect = Rect.new(x + offset_x, y, width, height)
  2507. contents.stretch_blt(rect, @subbar_empty, @subbar_empty.rect)
  2508. end
  2509.  
  2510. def draw_arcana_rank(arcana, x, y)
  2511. start_x = x + 100
  2512. start_y = y
  2513.  
  2514. rank = $game_variables[arcana.rank_var_id]
  2515. rank_str = sprintf("Rank %i", rank)
  2516. w = text_size(rank_str).width
  2517. h = text_size(rank_str).height
  2518. draw_text(start_x, start_y, w, h, rank_str)
  2519.  
  2520. start_y += h
  2521.  
  2522. bar_width = contents.width - start_x
  2523. rect = Rect.new(start_x, start_y, bar_width, @progress_bar.height)
  2524. contents.stretch_blt(rect, @progress_bar, @progress_bar.rect)
  2525. subbar_width = (bar_width.to_f) / arcana.max_rank
  2526.  
  2527. arcana_rank = $game_variables[arcana.rank_var_id]
  2528. for i in 0...arcana_rank
  2529. draw_rank_progress(start_x, start_y, i, subbar_width)
  2530. end
  2531.  
  2532. for i in arcana_rank...arcana.max_rank
  2533. draw_rank_remaining(start_x, start_y, i, subbar_width)
  2534. end
  2535. end
  2536.  
  2537. def draw_item_background(index)
  2538. if index == @pending_index
  2539. contents.fill_rect(item_rect(index), pending_color)
  2540. end
  2541. end
  2542.  
  2543. def draw_item(index)
  2544. arcana = @arcanas[index]
  2545.  
  2546. rect = item_rect(index)
  2547. draw_item_background(index)
  2548. draw_arcana(arcana, rect.x + 1, rect.y + 1)
  2549. draw_arcana_rank(arcana, rect.x + 1, rect.y + 1)
  2550. end
  2551.  
  2552. def current_item_enabled?
  2553. return true
  2554. end
  2555.  
  2556. def process_ok
  2557. super
  2558. @selected_arcana = @arcanas[index]
  2559. end
  2560.  
  2561. def select_last
  2562. if $game_party.menu_persona.nil?
  2563. select(0)
  2564. else
  2565. select($game_party.menu_persona.index || 0)
  2566. end
  2567. end
  2568.  
  2569. def pending_index=(index)
  2570. last_pending_index = @pending_index
  2571. @pending_index = index
  2572. redraw_item(@pending_index)
  2573. redraw_item(last_pending_index)
  2574. end
  2575.  
  2576. def selected_arcana
  2577. return @arcanas[@index]
  2578. end
  2579. end
  2580.  
  2581. class Window_MenuCommand < Window_Command
  2582. alias persona_arcana_mc make_command_list
  2583. def make_command_list
  2584. persona_arcana_mc
  2585. add_arcana_command
  2586. end
  2587.  
  2588. def add_arcana_command
  2589. # add arcana command to main menu
  2590. name = Persona::ARCANA_MENU_NAME
  2591. ext = nil
  2592. command = { :name=>name,
  2593. :symbol=>:social_links,
  2594. :enabled=>main_commands_enabled,
  2595. :ext=>ext}
  2596. index = Persona::ARCANA_MENU_COMMAND_INDEX - 1
  2597. index = [index, @list.length].min
  2598. @list.insert(index, command)
  2599. end
  2600. end
  2601.  
  2602. class Window_SocialLinkInfo < Window_Base
  2603. def initialize(x, y, social_link)
  2604. @window_height = line_height * 4
  2605. @window_width = Graphics.width - x
  2606. y = Graphics.height - @window_height
  2607. super(x, y, @window_width, @window_height)
  2608. @social_link = social_link
  2609. self.openness = 0
  2610. end
  2611.  
  2612. def social_link=(new_link)
  2613. @social_link = new_link
  2614. refresh
  2615. end
  2616.  
  2617. def window_width
  2618. @window_width
  2619. end
  2620.  
  2621. def window_height
  2622. @window_height
  2623. end
  2624.  
  2625. def draw_link_name
  2626. name = @social_link.name
  2627. w = window_width
  2628. h = text_size(name).height
  2629. draw_text(0, 0, w, h, name)
  2630. end
  2631.  
  2632. def draw_link_info
  2633. text = @social_link.social_description
  2634.  
  2635. words = text.split(" ")
  2636. text_line = words[0]
  2637. line_num = 1
  2638. words.size.times do |i|
  2639. if i == words.size - 1
  2640. line_size = text_size(text_line)
  2641. w = window_width
  2642. h = line_size.height
  2643. draw_text(0, line_num*h, w, h, text_line)
  2644. break
  2645. end
  2646.  
  2647. new_line = text_line + " " + words[i + 1]
  2648. line_size = text_size(new_line)
  2649. if line_size.width > window_width - standard_padding * 2
  2650. w = line_size.width
  2651. h = line_size.height
  2652. draw_text(0, line_num*h, w, h, text_line)
  2653. line_num += 1
  2654. text_line = words[i + 1]
  2655. else
  2656. text_line += ((text_line.size == 0 ? "" : " ") + words[i + 1])
  2657. end
  2658. end
  2659. end
  2660.  
  2661. def refresh
  2662. contents.clear
  2663. return if @social_link.nil?
  2664. draw_link_name
  2665. draw_link_info
  2666. end
  2667. end
  2668.  
  2669. class Window_SocialLinks < Window_Command
  2670. def initialize(arcana, x, y)
  2671. @arcana = arcana
  2672. @social_links_ids = @arcana.social_links
  2673. super(x, y)
  2674. select_last
  2675. self.openness = 0
  2676. end
  2677.  
  2678. def arcana=(arcana)
  2679. return if @arcana == arcana
  2680. @arcana = arcana
  2681. @social_links_ids = @arcana.social_links
  2682. refresh
  2683. select_last
  2684. end
  2685.  
  2686. def selected_social_link
  2687. return nil if @social_links_ids[@index].nil?
  2688. $game_actors[@social_links_ids[@index]]
  2689. end
  2690.  
  2691. def refresh
  2692. contents.clear
  2693. draw_all_items
  2694. end
  2695.  
  2696. def window_width
  2697. Graphics.width * 0.3
  2698. end
  2699.  
  2700. def window_height
  2701. [@arcana.social_links.size, 1].max * line_height + standard_padding * 2
  2702. end
  2703.  
  2704. def item_width
  2705. (width - standard_padding * 2 + spacing) / col_max - spacing
  2706. end
  2707.  
  2708. def item_height
  2709. (height - standard_padding * 2) / visible_line_number
  2710. end
  2711.  
  2712. def visible_line_number
  2713. @arcana.social_links.size == 0 ? 1 : @arcana.social_links.size
  2714. end
  2715.  
  2716. def item_max
  2717. @arcana.social_links.size
  2718. end
  2719.  
  2720. def process_handling
  2721. return unless open? && active
  2722. return true if Input.trigger?(:C)
  2723. super
  2724. end
  2725.  
  2726. def draw_item(index)
  2727. return if @social_links_ids.size == 0
  2728. social_link = @social_links_ids[index]
  2729. social_link = $game_actors[social_link]
  2730.  
  2731. rect = item_rect_for_text(index)
  2732. draw_actor_name(social_link, rect.x + 1, rect.y + 1, window_width - standard_padding)
  2733. end
  2734.  
  2735. alias persona_arcana_pcm process_cursor_move
  2736. def process_cursor_move
  2737. last_index = @index
  2738. persona_arcana_pcm
  2739. if @index != last_index
  2740. call_handler(:selection_changed)
  2741. end
  2742. end
  2743.  
  2744. def select_last
  2745. select(0)
  2746. end
  2747.  
  2748. def pending_index=(index)
  2749. last_pending_index = @pending_index
  2750. @pending_index = index
  2751. redraw_item(@pending_index)
  2752. redraw_item(last_pending_index)
  2753. end
  2754.  
  2755. def update
  2756. super
  2757. self.hide if @arcana.social_links.size == 0
  2758. end
  2759. end
  2760.  
  2761. class Scene_Arcanas < Scene_Base
  2762. def start
  2763. super
  2764. create_background
  2765. create_rank_window
  2766. end
  2767.  
  2768. def terminate
  2769. super
  2770. dispose_background
  2771. end
  2772.  
  2773. def create_background
  2774. @background_sprite = Sprite.new
  2775. @background_sprite.bitmap = SceneManager.background_bitmap
  2776. @background_sprite.color.set(16, 16, 16, 128)
  2777. end
  2778.  
  2779. def dispose_background
  2780. @background_sprite.dispose
  2781. end
  2782.  
  2783. def create_rank_window
  2784. @arcanas_window = Window_Arcanas.new
  2785. @arcanas_window.select_last
  2786. @arcanas_window.set_handler(:ok, method(:on_arcana_ok))
  2787. @arcanas_window.set_handler(:cancel, method(:return_scene))
  2788. @arcanas_window.open
  2789. end
  2790.  
  2791. def create_social_links_window
  2792. arcana = @arcanas_window.selected_arcana
  2793. x = 0
  2794. y = @info_window.height
  2795. @social_links_window = Window_SocialLinks.new(arcana, x, y)
  2796. @social_links_window.select_last
  2797. @social_links_window.refresh
  2798. @social_links_window.open
  2799. @social_links_window.set_handler(:cancel, method(:arcana_info_cancel))
  2800. @social_links_window.set_handler(:selection_changed, method(:social_link_changed))
  2801. @social_links_window.open
  2802. end
  2803.  
  2804. def create_description_window
  2805. @info_window = Window_ArcanaInfo.new(@arcanas_window.selected_arcana)
  2806. @info_window.refresh
  2807. @info_window.open
  2808. end
  2809.  
  2810. def create_social_link_info_window
  2811. return if @social_links_window.selected_social_link.nil?
  2812. x = @social_links_window.width
  2813. y = @social_links_window.y + @social_links_window.height
  2814. social_link = @social_links_window.selected_social_link
  2815. @social_link_info_window = Window_SocialLinkInfo.new(x, y, social_link)
  2816. @social_link_info_window.refresh
  2817. @social_link_info_window.open
  2818. end
  2819.  
  2820. def change_social_link
  2821. @social_link.dispose if @social_link
  2822. return if @social_links_window.selected_social_link.nil?
  2823. social_link = @social_links_window.selected_social_link
  2824. file_name = social_link.name.downcase.gsub(" ", "_")
  2825. @social_link = Sprite_SocialLink.new(@viewport, file_name)
  2826. x = @social_links_window.width
  2827. @social_link.x = x + (Graphics.width - x) / 2 - @social_link.width / 2
  2828. @social_link.y = @info_window.height
  2829. end
  2830.  
  2831. def social_link_changed
  2832. @social_link_info_window.social_link = @social_links_window.selected_social_link
  2833. change_social_link
  2834. end
  2835.  
  2836. def on_arcana_ok
  2837. @arcanas_window.hide
  2838. create_description_window
  2839. create_social_links_window
  2840. change_social_link
  2841. create_social_link_info_window
  2842. end
  2843.  
  2844. def arcana_info_cancel
  2845. @social_links_window.close
  2846. @info_window.close
  2847. @social_link_info_window.close if @social_link_info_window
  2848. @social_link.dispose if @social_link
  2849. @arcanas_window.show
  2850. @arcanas_window.active = true
  2851. end
  2852. end
  2853.  
  2854. class Scene_Menu < Scene_MenuBase
  2855. alias persona_arcana_ccw create_command_window
  2856. def create_command_window
  2857. persona_arcana_ccw
  2858. @command_window.set_handler(:social_links, method(:social_links))
  2859. end
  2860.  
  2861. def social_links
  2862. SceneManager.call(Scene_Arcanas)
  2863. end
  2864. end
  2865.  
  2866. #-------------------------------------------------------------------------------
  2867. # _____ _ _ _ __ __ _ _
  2868. # | ____|_ _____ | |_ _| |_(_) ___ _ __ | \/ | ___ __| |_ _| | ___
  2869. # | _| \ \ / / _ \| | | | | __| |/ _ \| '_ \ | |\/| |/ _ \ / _` | | | | |/ _ \
  2870. # | |___ \ V / (_) | | |_| | |_| | (_) | | | | | | | | (_) | (_| | |_| | | __/
  2871. # |_____| \_/ \___/|_|\__,_|\__|_|\___/|_| |_| |_| |_|\___/ \__,_|\__,_|_|\___|
  2872. #
  2873. # Evolution Module
  2874. #-------------------------------------------------------------------------------
  2875. class RPG::Actor < RPG::BaseItem
  2876. def evolve_at
  2877. note =~ /<Arcana evolve rank: (\d+)>/ ? $1.to_i : -1
  2878. end
  2879.  
  2880. def evolve_to
  2881. note =~ /<Evolve to: (.*)>/ ? $1 : ""
  2882. end
  2883. end
  2884.  
  2885. class Game_Actor < Game_Battler
  2886. include Persona
  2887.  
  2888. attr_reader :evolve_at, :evolve_to
  2889. alias persona_evolve_sp setup_persona
  2890. def setup_persona
  2891. persona_evolve_sp
  2892. @evolve_at = arcana? ? actor.evolve_at : -1
  2893. @evolve_to = arcana? ? actor.evolve_to : ""
  2894. end
  2895. end
  2896.  
  2897. class Game_Player < Game_Character
  2898. alias persona_evolve_aru arcana_rank_up
  2899. def arcana_rank_up(arcana_name)
  2900. persona_evolve_aru(arcana_name)
  2901. check_party_persona_evolve
  2902. end
  2903.  
  2904. def check_party_persona_evolve
  2905. # check members' personas first and if one will be evolved equip it
  2906. # automatically to the actor that had the persona equipped
  2907. members = $game_party.members
  2908. members.each do |m|
  2909. next if m.persona.nil?
  2910. persona = m.persona
  2911. if persona.arcana_rank == persona.evolve_at
  2912. evolved_persona = evolve_persona(persona)
  2913. m.change_persona(evolved_persona)
  2914. play_evolution
  2915. $game_party.menu_persona = evolved_persona
  2916. SceneManager.call(Scene_EvolvedPersona)
  2917. end
  2918. end
  2919.  
  2920. # find all others and evolve them
  2921. members_personas = members.collect{|m| m.persona }
  2922. personas = $game_party.personas
  2923. personas.each do |p|
  2924. next if !members_personas.find{|mp| mp == p}.nil?
  2925. if p.arcana_rank == p.evolve_at
  2926. evolved_persona = evolve_persona(p)
  2927. play_evolution
  2928. $game_party.menu_persona = evolved_persona
  2929. SceneManager.call(Scene_EvolvedPersona)
  2930. end
  2931. end
  2932. end
  2933.  
  2934. def evolve_persona(persona)
  2935. $game_party.remove_persona(persona.id)
  2936. evolved_persona = $data_actors.find{|a| !a.nil? && a.name == persona.evolve_to}
  2937. evolved_persona = $game_personas[evolved_persona.id]
  2938. $game_party.add_persona(evolved_persona.id)
  2939. $game_variables[EVOLVING_PERSONA_VAR_ID] = persona.name
  2940. $game_variables[RESULTING_PERSONA_VAR_ID] = evolved_persona.name
  2941. return evolved_persona
  2942. end
  2943.  
  2944. def play_evolution
  2945. common_event = $data_common_events[Persona::COMMON_EVENT_ID]
  2946. if common_event
  2947. child = Game_Interpreter.new
  2948. child.setup(common_event.list, 0)
  2949. child.run
  2950. end
  2951. end
  2952. end
  2953.  
  2954. class Scene_EvolvedPersona < Scene_Base
  2955. def start
  2956. super
  2957. create_background
  2958. @persona = $game_party.menu_persona
  2959. show_evolved
  2960. end
  2961.  
  2962. def show_evolved
  2963. create_status_window
  2964. @status_window.persona = @persona
  2965. @status_window.activate
  2966. @status_window.open
  2967. end
  2968.  
  2969. def terminate
  2970. super
  2971. dispose_background
  2972. end
  2973.  
  2974. def create_background
  2975. @background_sprite = Sprite.new
  2976. @background_sprite.bitmap = SceneManager.background_bitmap
  2977. @background_sprite.color.set(16, 16, 16, 128)
  2978. end
  2979.  
  2980. def dispose_background
  2981. @background_sprite.dispose
  2982. end
  2983.  
  2984. def create_status_window
  2985. @status_window = Window_PersonaStatus.new($game_party.menu_persona)
  2986. @status_window.set_handler(:ok, method(:close_status))
  2987. @status_window.set_handler(:cancel, method(:close_status))
  2988. @status_window.show.activate
  2989. end
  2990.  
  2991. def close_status
  2992. @status_window.close
  2993. SceneManager.return
  2994. end
  2995. end
  2996.  
  2997. #-------------------------------------------------------------------------------
  2998. # _____ _ __ __ _ _
  2999. # | ___| _ ___(_) ___ _ __ | \/ | ___ __| |_ _| | ___
  3000. # | |_ | | | / __| |/ _ \| '_ \ | |\/| |/ _ \ / _` | | | | |/ _ \
  3001. # | _|| |_| \__ \ | (_) | | | | | | | | (_) | (_| | |_| | | __/
  3002. # |_| \__,_|___/_|\___/|_| |_| |_| |_|\___/ \__,_|\__,_|_|\___|
  3003. #
  3004. # Fusion Module
  3005. #-------------------------------------------------------------------------------
  3006. class RPG::Actor < RPG::BaseItem
  3007. def fuse_parents
  3008. # matches all the <Fusion parents> tag in note
  3009. matches = note.scan(/<Fusion parents: (\d+),[ ]?(\d+)>/)
  3010. if matches.empty?
  3011. return nil
  3012. else
  3013. # for each <Fusion parents> tag, append the parents to a list and return
  3014. parents = []
  3015. for m in matches
  3016. parents.push([m[0].to_i, m[1].to_i])
  3017. end
  3018. return parents
  3019. end
  3020. end
  3021.  
  3022. def special_fusion
  3023. # get ids required for special fusion. returns empty list if there are no ids
  3024. # as it is now it matches more than 3 ids, but will return only the first 3
  3025. # kept as is for the future
  3026. matches = /<Special fusion: (\d+(,[ ]?\d+)*)?>/.match(note)
  3027. return [] if matches.nil?
  3028. parents = matches[1]
  3029. parents.split(",").collect{ |i| i.to_i }[0...3]
  3030. end
  3031.  
  3032. def are_parents(persona_a_id, persona_b_id)
  3033. parents_pairs = fuse_parents # get all parents of persona
  3034. return false if parents_pairs.nil?
  3035. if Persona::ORDER_MATTERS
  3036. # if order matters search for index of pair and return true if found
  3037. return !parents_pairs.index([persona_a_id, persona_b_id]).nil?
  3038. else
  3039. # sort each pair and search for index of pair provided
  3040. return !parents_pairs.map{|p| p.sort }.index([persona_a_id, persona_b_id].sort).nil?
  3041. end
  3042. end
  3043.  
  3044. def are_special_parents(parents)
  3045. s_p = special_fusion
  3046. if Persona::ORDER_MATTERS
  3047. return parents[0] == s_p[0] && parents[1] == s_p[1] && parents[2] == s_p[2]
  3048. else
  3049. return parents.inject(true){|r, p| r && s_p.index(p).nil? }
  3050. end
  3051. end
  3052. end
  3053.  
  3054. class Game_System
  3055. attr_reader :fuse_count
  3056. alias persona_fuse_init initialize
  3057. def initialize
  3058. persona_fuse_init
  3059. @fuse_count = 0
  3060. end
  3061.  
  3062. def fuse_personas(fuse_count)
  3063. @fuse_count = fuse_count
  3064. SceneManager.call(Scene_Fuse)
  3065. Fiber.yield
  3066. end
  3067.  
  3068. def get_fusion_child(parent_a, parent_b)
  3069. # get all personas that have parents
  3070. children = $data_actors.select{|a| !a.nil? && a.persona? && !a.fuse_parents.nil? }
  3071. # find child of those parents
  3072. child = children.find{|a| a.are_parents(parent_a.id, parent_b.id) }
  3073. return nil if child.nil?
  3074. return $game_actors[child.id]
  3075. end
  3076.  
  3077. def get_special_fusion(parents)
  3078. # get all
  3079. parents_ids = parents.collect{|p| p.id}
  3080. special = $data_actors.find{|a| !a.nil? && a.are_special_parents(parents_ids) }
  3081. return nil if special.nil?
  3082. return $game_actors[special.id]
  3083. end
  3084. end
  3085.  
  3086. class Window_ExtraExp < Window_Base
  3087. def initialize(x, y)
  3088. height = line_height * 2
  3089. super(x, y, 180, height)
  3090. @current_exp = 0
  3091. @exp_changed = false
  3092. self.visible = false
  3093. end
  3094.  
  3095. def set_width(txt)
  3096. contents.clear
  3097. if text_size(txt).width > self.width - standard_padding * 2
  3098. self.width = text_size(txt).width + standard_padding * 2
  3099. create_contents
  3100. end
  3101. end
  3102.  
  3103. def text=(txt)
  3104. draw_text(0, 0, self.width - standard_padding, line_height, txt)
  3105. end
  3106.  
  3107. def exp=(exp)
  3108. @current_exp = exp
  3109. @exp_changed = true
  3110. end
  3111.  
  3112. def update
  3113. super
  3114. update_exp if @exp_changed
  3115. end
  3116.  
  3117. def update_exp
  3118. contents.clear
  3119. draw_text(0, 0, self.width - standard_padding, line_height, "Bonus EXP:")
  3120. x = text_size("Bonus EXP:").width
  3121. draw_text(x - 10, 0, self.width - standard_padding - x, line_height, @current_exp, 2)
  3122. end
  3123. end
  3124.  
  3125. class Window_Fuse < Window_Command
  3126. include Persona
  3127.  
  3128. attr_reader :result, :children
  3129. def initialize(fuse_count)
  3130. @selected_personas = []
  3131. @fuse_count = fuse_count
  3132. @children = []
  3133. @result = nil
  3134. @personas = available_personas
  3135. super(0, 0)
  3136. select_last
  3137. end
  3138.  
  3139. def selected_personas
  3140. @selected_personas
  3141. end
  3142.  
  3143. def reset
  3144. self.active = true
  3145. select_last
  3146. @selected_personas = []
  3147. @result = nil
  3148. @personas = available_personas
  3149. refresh
  3150. end
  3151.  
  3152. def refresh
  3153. contents.clear
  3154. refresh_children
  3155. draw_all_items
  3156. end
  3157.  
  3158. def refresh_children
  3159. @children.clear
  3160. # calculate children only when the last persona is not selected
  3161. return if @fuse_count - @selected_personas.size > 1
  3162. parent_a = @selected_personas[0]
  3163.  
  3164.  
  3165. if @fuse_count == 2
  3166. # normal fusion
  3167. for parent_b in @personas
  3168. child = $game_system.get_fusion_child(parent_a, parent_b)
  3169. @children.push(child)
  3170. end
  3171. elsif @fuse_count == 3
  3172. # special fusion
  3173. for persona_c in @personas
  3174. special_parents = @selected_personas + [persona_c]
  3175. child = $game_system.get_special_fusion(special_parents)
  3176. @children.push(child)
  3177. end
  3178. end
  3179. end
  3180.  
  3181. def window_width
  3182. Graphics.width / 2
  3183. end
  3184.  
  3185. def window_height
  3186. Graphics.height
  3187. end
  3188.  
  3189. def item_width
  3190. (width - standard_padding * 2 + spacing) / col_max - spacing
  3191. end
  3192.  
  3193. def item_height
  3194. line_height
  3195. end
  3196.  
  3197. def visible_line_number
  3198. 8
  3199. end
  3200.  
  3201. def item_max
  3202. @personas.size
  3203. end
  3204.  
  3205. def process_handling
  3206. return unless open? && active
  3207. return process_status if status_enabled? && Input.trigger?(:X)
  3208. return process_cancel if cancel_enabled? && Input.trigger?(:B)
  3209. return process_ok if ok_enabled? && Input.trigger?(:C)
  3210. end
  3211.  
  3212. def process_status
  3213. Sound.play_ok
  3214. $game_party.menu_persona = @personas[index]
  3215. call_status_handler
  3216. end
  3217.  
  3218. def call_status_handler
  3219. call_handler(:status)
  3220. end
  3221. def status_enabled?
  3222. handle?(:status)
  3223. end
  3224.  
  3225. def available_personas
  3226. actors = $game_party.members.select{ |a| !CAN_USE_ACTORS_PERSONAS.index(a.id).nil? }
  3227. personas = actors.inject([]){|res, a| res += $game_party.actors_personas(a.id)}
  3228. return personas
  3229. end
  3230.  
  3231. def process_cancel
  3232. Sound.play_cancel
  3233. Input.update
  3234. if @selected_personas.size == 0
  3235. call_return_handler
  3236. deactivate
  3237. else
  3238. @selected_personas.pop
  3239. refresh
  3240. call_cancel_handler
  3241. end
  3242. end
  3243.  
  3244. def call_cancel_handler
  3245. call_handler(:cancel)
  3246. end
  3247.  
  3248. def cancel_enabled?
  3249. handle?(:cancel)
  3250. end
  3251.  
  3252. def call_return_handler
  3253. call_handler(:return)
  3254. end
  3255.  
  3256. def process_ok
  3257. if current_item_enabled?
  3258. persona = @personas[index]
  3259. @selected_personas.push(persona)
  3260. Sound.play_ok
  3261. if @selected_personas.size == @fuse_count
  3262. # the result has the same index with the last persona picked
  3263. @result = @children[index]
  3264. call_fuse_handler
  3265. else
  3266. refresh
  3267. call_ok_handler
  3268. end
  3269. else
  3270. Sound.play_buzzer
  3271. end
  3272. end
  3273.  
  3274. def call_fuse_handler
  3275. call_handler(:fuse)
  3276. end
  3277.  
  3278. def fuse_enabled?
  3279. handle?(:fuse)
  3280. end
  3281.  
  3282. def draw_actor_level(persona, x, y)
  3283. change_color(system_color)
  3284. draw_text(x, y, 32, line_height, Vocab::level_a)
  3285. change_color(normal_color)
  3286. offset_x = text_size(Vocab::level_a).width
  3287. draw_text(x + offset_x, y, 24, line_height, persona.level)
  3288. end
  3289.  
  3290. def draw_persona_info(persona, x, y, enabled)
  3291. change_color(normal_color, enabled)
  3292. offset_x = 0
  3293.  
  3294. draw_actor_class(persona, x + offset_x, y)
  3295. offset_x += text_size(persona.class.name + " ").width
  3296.  
  3297. draw_actor_level(persona, x + offset_x, y)
  3298. offset_x += text_size(Vocab::level_a + persona.level.to_s + " ").width
  3299.  
  3300. draw_actor_name(persona, x + offset_x, y)
  3301. change_color(normal_color)
  3302. end
  3303.  
  3304. def draw_item_background(index)
  3305. if !@selected_personas.index(@personas[index]).nil?
  3306. color = pending_color
  3307. color.alpha = 100
  3308. contents.fill_rect(item_rect(index), color)
  3309. end
  3310. end
  3311.  
  3312. def draw_item(index)
  3313. persona = @personas[index]
  3314.  
  3315. enabled = !@selected_personas.index(persona).nil?
  3316. rect = item_rect(index)
  3317. draw_item_background(index)
  3318. draw_persona_info(persona, rect.x, rect.y, enabled)
  3319. end
  3320.  
  3321. def current_item_enabled?
  3322. persona = @personas[index]
  3323. return false if !@selected_personas.index(persona).nil?
  3324. return true if @selected_personas.size == 0
  3325. return true if @selected_personas.size < @fuse_count - 1
  3326. return !@children[index].nil?
  3327. end
  3328.  
  3329. def select_last
  3330. select(0)
  3331. end
  3332.  
  3333. def pending_index=(index)
  3334. last_pending_index = @pending_index
  3335. @pending_index = index
  3336. redraw_item(@pending_index)
  3337. redraw_item(last_pending_index)
  3338. end
  3339. end
  3340.  
  3341. class Window_FuseResults < Window_Base
  3342. include Persona
  3343.  
  3344. def initialize
  3345. @children = []
  3346. super(window_width, 0, window_width, window_height)
  3347. end
  3348.  
  3349. def children=(children)
  3350. @children = children
  3351. refresh
  3352. end
  3353.  
  3354. def refresh
  3355. contents.clear
  3356. @children.size.times{|i| draw_item(i)}
  3357. end
  3358.  
  3359. def window_width
  3360. Graphics.width / 2
  3361. end
  3362.  
  3363. def window_height
  3364. Graphics.height
  3365. end
  3366.  
  3367. def col_max
  3368. return 1
  3369. end
  3370.  
  3371. def spacing
  3372. return 32
  3373. end
  3374.  
  3375. def item_width
  3376. (width - standard_padding * 2 + spacing) / col_max - spacing
  3377. end
  3378.  
  3379. def item_height
  3380. line_height
  3381. end
  3382.  
  3383. def item_max
  3384. @children.size
  3385. end
  3386.  
  3387. def draw_actor_level(persona, x, y, enabled=true)
  3388. change_color(system_color, enabled)
  3389. draw_text(x, y, 32, line_height, Vocab::level_a)
  3390. change_color(normal_color, enabled)
  3391. offset_x = text_size(Vocab::level_a).width
  3392. draw_text(x + offset_x, y, 24, line_height, persona.level)
  3393. end
  3394.  
  3395. def draw_actor_class(actor, x, y, width = 112, enabled=true)
  3396. change_color(normal_color, enabled)
  3397. draw_text(x, y, width, line_height, actor.class.name)
  3398. end
  3399.  
  3400. def draw_actor_name(actor, x, y, width = 112, enabled=true)
  3401. change_color(hp_color(actor), enabled)
  3402. draw_text(x, y, width, line_height, actor.name)
  3403. end
  3404.  
  3405. def draw_item_background(index)
  3406. if @children[index].special_persona?
  3407. contents.fill_rect(item_rect(index), Persona::SPECIAL_FUSION_COLOR)
  3408. end
  3409. end
  3410.  
  3411. def draw_persona_info(persona, x, y, enabled)
  3412. offset_x = 0
  3413.  
  3414. draw_actor_class(persona, x + offset_x, y, 112, enabled)
  3415. offset_x += text_size(persona.class.name + " ").width
  3416.  
  3417. draw_actor_level(persona, x + offset_x, y, enabled)
  3418. offset_x += text_size(Vocab::level_a + persona.level.to_s + " ").width
  3419.  
  3420. draw_actor_name(persona, x + offset_x, y, 112, enabled)
  3421. end
  3422.  
  3423. def item_rect(index)
  3424. rect = Rect.new
  3425. rect.width = item_width
  3426. rect.height = item_height
  3427. rect.x = index % col_max * (item_width + spacing)
  3428. rect.y = index / col_max * item_height
  3429. rect
  3430. end
  3431.  
  3432. def draw_item(index)
  3433. child = @children[index]
  3434. return if child.nil?
  3435. rect = item_rect(index)
  3436. users = $game_party.members.select{|m| !child.users.index(m.id).nil? }
  3437. enabled = true
  3438. draw_item_background(index)
  3439. draw_persona_info(child, rect.x, rect.y, enabled)
  3440. end
  3441. end
  3442.  
  3443. class Window_PersonaStatus < Window_Command
  3444. alias persona_fuse_init initialize
  3445. def initialize(persona)
  3446. persona_fuse_init(persona)
  3447. @bonus_exp = 0
  3448. @start_exp = false
  3449. @step = 0
  3450. @ok_enabled = false
  3451. end
  3452.  
  3453. def disable_ok
  3454. @ok_enabled = true
  3455. end
  3456.  
  3457. def enable_ok
  3458. @ok_enabled = false
  3459. end
  3460.  
  3461. alias persona_ph process_handling
  3462. def process_handling
  3463. if SceneManager.scene_is?(Scene_Fuse)
  3464. return process_ok if ok_enabled? && Input.trigger?(:C)
  3465. return process_cancel if cancel_enabled? && Input.trigger?(:B)
  3466. else
  3467. persona_ph
  3468. end
  3469. end
  3470.  
  3471. def ok_enabled?
  3472. handle?(:ok) && !@ok_enabled
  3473. end
  3474.  
  3475. def process_ok
  3476. Sound.play_ok
  3477. Input.update
  3478. deactivate
  3479. call_ok_handler
  3480. end
  3481.  
  3482. def bonus_exp=(exp)
  3483. @bonus_exp = exp
  3484. @step = @bonus_exp/30
  3485. end
  3486.  
  3487. def bonus_exp
  3488. @bonus_exp
  3489. end
  3490.  
  3491. def done_exp
  3492. @bonus_exp == 0
  3493. end
  3494.  
  3495. alias persona_fuse_u update
  3496. def update
  3497. update_bonus_exp
  3498. persona_fuse_u
  3499. end
  3500.  
  3501. def start_exp
  3502. @start_exp = true
  3503. end
  3504.  
  3505. def update_bonus_exp
  3506. if @start_exp
  3507. @bonus_exp = [@bonus_exp-@step, 0].max
  3508. new_exp = @persona.exp + ([@step, @bonus_exp].min * @persona.final_exp_rate).to_i
  3509. @persona.change_exp(new_exp, false)
  3510. @start_exp = @bonus_exp != 0
  3511. refresh
  3512. end
  3513. end
  3514. end
  3515.  
  3516. class Scene_Fuse < Scene_Base
  3517. def start
  3518. super
  3519. create_background
  3520. create_fuse_window
  3521. create_result_window
  3522. create_message_window
  3523. create_extra_exp_window
  3524. create_status_window
  3525. end
  3526.  
  3527. def terminate
  3528. super
  3529. dispose_background
  3530. end
  3531.  
  3532. def create_extra_exp_window
  3533. @extra_exp_window = Window_ExtraExp.new(350, 24 * 5)
  3534. end
  3535.  
  3536. def create_message_window
  3537. $game_message.clear
  3538. @message_window = Window_Message.new
  3539. @choice = -1
  3540. end
  3541.  
  3542. def create_fuse_window
  3543. @fuse_window = Window_Fuse.new($game_system.fuse_count)
  3544. @fuse_window.select_last
  3545. # called when a new persona is selected
  3546. @fuse_window.set_handler(:ok, method(:on_process_ok))
  3547. # called when the last persona for the fusion was selected and opens the status window
  3548. @fuse_window.set_handler(:fuse, method(:fuse))
  3549. # called when there are no selected personas and leaves the scene
  3550. @fuse_window.set_handler(:return, method(:return_scene))
  3551. # called when there are selected personas and removes the last chosen one
  3552. @fuse_window.set_handler(:cancel, method(:on_fuse_cancel))
  3553. # shows the selected persona's status
  3554. @fuse_window.set_handler(:status, method(:on_status_ok))
  3555. @fuse_window.z -= 2
  3556. end
  3557.  
  3558. def create_status_window
  3559. @status_window = Window_PersonaStatus.new($game_party.menu_persona)
  3560. # called when confirming a fusion
  3561. @status_window.set_handler(:ok, method(:fuse_confirm))
  3562. # called when viewing a persona's status and returns to fuse windows
  3563. @status_window.set_handler(:cancel, method(:return_status))
  3564. @status_window.deactivate
  3565. @status_window.z -= 1
  3566. end
  3567.  
  3568. def create_result_window
  3569. @results_window = Window_FuseResults.new
  3570. @results_window.z -= 2
  3571. end
  3572.  
  3573. def wait_for_message
  3574. @status_window.deactivate
  3575. @message_window.activate
  3576. @message_window.update
  3577. update_basic while $game_message.visible
  3578. @status_window.activate
  3579. end
  3580.  
  3581. def on_status_ok
  3582. @status_window.persona = $game_party.menu_persona
  3583. @status_window.show
  3584. @status_window.disable_ok
  3585. @fuse_window.deactivate
  3586. @status_window.activate
  3587. end
  3588.  
  3589. def return_status
  3590. return if @message_window.open?
  3591. @status_window.deactivate
  3592. @status_window.hide
  3593. @extra_exp_window.hide
  3594.  
  3595. @fuse_window.activate
  3596. @fuse_window.selected_personas.pop if @fuse_window.selected_personas.length == $game_system.fuse_count
  3597. end
  3598.  
  3599. def create_background
  3600. @background_sprite = Sprite.new
  3601. @background_sprite.bitmap = SceneManager.background_bitmap
  3602. @background_sprite.color.set(16, 16, 16, 128)
  3603. end
  3604.  
  3605. def dispose_background
  3606. @background_sprite.dispose
  3607. end
  3608.  
  3609. def on_process_ok
  3610. if @fuse_window.selected_personas.size == $game_system.fuse_count - 1
  3611. @results_window.children = @fuse_window.children
  3612. end
  3613. end
  3614.  
  3615. def on_fuse_cancel
  3616. @results_window.children = @fuse_window.children
  3617. end
  3618.  
  3619. def fuse
  3620. @status_window.persona = $game_personas[@fuse_window.result.id]
  3621. @fuse_window.deactivate
  3622. @status_window.enable_ok
  3623.  
  3624. persona = @fuse_window.result
  3625. bonus_exp = Persona.FUSION_EXP_CALC(persona).to_i
  3626. @status_window.bonus_exp = bonus_exp
  3627. txt = "Bonus EXP:"
  3628. @extra_exp_window.text = txt
  3629. @extra_exp_window.exp = bonus_exp
  3630. @extra_exp_window.set_width("Bonus EXP:#{bonus_exp}")
  3631.  
  3632. @status_window.show.activate
  3633. @extra_exp_window.show
  3634. end
  3635.  
  3636. def wait_for_exp
  3637. @status_window.start_exp
  3638. while !@status_window.done_exp
  3639. @extra_exp_window.exp= @status_window.bonus_exp
  3640.  
  3641. @extra_exp_window.update
  3642. @status_window.update
  3643. Graphics.update
  3644. end
  3645. @extra_exp_window.exp = @status_window.bonus_exp
  3646.  
  3647. @extra_exp_window.update
  3648. @status_window.update
  3649. end
  3650.  
  3651. def fuse_confirm
  3652. return if @choice == 0 # return if already accepted fusion
  3653. return if @fuse_window.result.nil?
  3654. $game_message.add("Are you sure you want to create the #{@fuse_window.result.name}")
  3655. $game_message.add("persona?")
  3656. $game_message.choices.push("Yes")
  3657. $game_message.choices.push("No")
  3658. $game_message.choice_cancel_type = 2
  3659. $game_message.choice_proc = Proc.new {|n| @choice = n }
  3660. wait_for_message
  3661. if @choice == 0
  3662. wait_for_exp
  3663. fusing = @fuse_window.selected_personas.collect{|p| p.name }.join(" + ")
  3664. $game_message.add("Fused #{fusing} into\n#{@fuse_window.result.name}!")
  3665. wait_for_message
  3666. for persona in @fuse_window.selected_personas
  3667. $game_party.remove_persona(persona.id)
  3668. end
  3669. $game_party.add_persona(@status_window.persona.id)
  3670.  
  3671. @extra_exp_window.hide
  3672. @status_window.hide
  3673. @results_window.children = []
  3674. @fuse_window.reset
  3675. @choice = -1
  3676. else
  3677. @message_window.close
  3678. @choice = -1
  3679. return
  3680. end
  3681. end
  3682. end
  3683.  
  3684. #-------------------------------------------------------------------------------
  3685. # ____ _ __ __ _ __ __ _ _
  3686. # / ___|| |__ _ _ / _|/ _| | ___ | \/ | ___ __| |_ _| | ___
  3687. # \___ \| '_ \| | | | |_| |_| |/ _ \ | |\/| |/ _ \ / _` | | | | |/ _ \
  3688. # ___) | | | | |_| | _| _| | __/ | | | | (_) | (_| | |_| | | __/
  3689. # |____/|_| |_|\__,_|_| |_| |_|\___| |_| |_|\___/ \__,_|\__,_|_|\___|
  3690. #
  3691. # Shuffle Module
  3692. #-------------------------------------------------------------------------------
  3693. class RPG::Enemy < RPG::BaseItem
  3694. def drop_cards
  3695. return note.scan(/<Card drop: (.*), ([0-9][.]?[0-9]+)>/)
  3696. end
  3697. end
  3698.  
  3699. module Cache
  3700. def self.card(filename)
  3701. load_bitmap("Graphics/" + Persona::CARD_IMG_FOLDER, filename)
  3702. end
  3703. end
  3704.  
  3705. class Scene_Battle < Scene_Base
  3706. def hide_actor_window
  3707. @status_window.hide
  3708. 10.times do
  3709. @status_window.update
  3710. end
  3711. end
  3712. end
  3713.  
  3714. module BattleManager
  3715. class <<self
  3716. include Persona
  3717.  
  3718. attr_reader :cards_dropped
  3719.  
  3720. alias persona_shuffle_pv process_victory
  3721. def process_victory
  3722. @cards_dropped = $game_troop.make_drop_cards
  3723.  
  3724. @cards_dropped = $game_system.filter_cards(@cards_dropped)
  3725.  
  3726. if !@cards_dropped.empty?
  3727. SceneManager.scene.hide_actor_window
  3728. # call personastatus scene, start it and
  3729. # wait until scene has finished
  3730. # this is done because scene is not changing when called by the
  3731. # usual way (SceneManager.call(Scene_ForgetSkill)
  3732. # or maybe i'm doing something wrong (?). same with scene_personastatus
  3733. # in gain_exp method
  3734. SceneManager.call(Scene_Shuffle)
  3735. SceneManager.scene.start
  3736. wait_for_shuffle
  3737. end
  3738.  
  3739. if $game_system.shuffle_result == "Penalty"
  3740. # if player drew a penalty card then skip battle rewards
  3741. $game_message.add(PENALTY_CARD_RESULT_MSG)
  3742. $game_message.add(sprintf(Vocab::Victory, $game_party.name))
  3743. wait_for_message
  3744. SceneManager.return
  3745. battle_end(0)
  3746. replay_bgm_and_bgs
  3747. return true
  3748. else
  3749. if $game_system.shuffle_result == ""
  3750. $game_message.add(NO_CARD_RESULT_MSG)
  3751. elsif $game_system.shuffle_result == "Blank"
  3752. $game_message.add(BLANK_CARD_RESULT_MSG)
  3753. end
  3754. persona_shuffle_pv
  3755. end
  3756. end
  3757.  
  3758. alias persona_shuffle_ge gain_exp
  3759. def gain_exp
  3760. persona_shuffle_ge
  3761. $game_party.battle_personas.each do |m|
  3762. next if m.extra_skills.empty?
  3763. $game_party.menu_persona = m
  3764. SceneManager.call(Scene_ForgetSkill)
  3765. SceneManager.scene.start_without_bg
  3766. SceneManager.scene.show_message
  3767. SceneManager.scene.update while SceneManager.scene_is?(Scene_ForgetSkill)
  3768. end
  3769. end
  3770.  
  3771. alias persona_shuffle_bs battle_start
  3772. def battle_start
  3773. persona_shuffle_bs
  3774. $game_system.reset_shuffle_result
  3775. end
  3776.  
  3777. def wait_for_shuffle
  3778. # wait for shuffle_time to finish
  3779. SceneManager.scene.update while SceneManager.scene_is?(Scene_Shuffle)
  3780. Graphics.transition(30)
  3781. end
  3782. end
  3783. end
  3784.  
  3785. class Game_Enemy < Game_Battler
  3786. def make_drop_cards
  3787. cards = []
  3788. enemy.drop_cards.each do |card, prob|
  3789. if rand < prob.to_f * drop_item_rate
  3790. cards.push(card)
  3791. end
  3792. end
  3793. return cards
  3794. end
  3795. end
  3796.  
  3797. class Game_Message
  3798. alias persona_shuffle_init initialize
  3799. def initialize
  3800. persona_shuffle_init
  3801. shuffle_clear
  3802. end
  3803.  
  3804. def shuffle_busy?
  3805. shuffle_has_text?
  3806. end
  3807.  
  3808. def shuffle_clear
  3809. @shuffle_texts = []
  3810. end
  3811.  
  3812. def shuffle_add(text)
  3813. @shuffle_texts.push(text)
  3814. end
  3815.  
  3816. def shuffle_has_text?
  3817. @shuffle_texts.size > 0
  3818. end
  3819.  
  3820. def shuffle_all_text
  3821. @shuffle_texts.inject("") {|r, text| r += text + "\n" }
  3822. end
  3823. end
  3824.  
  3825. class Game_System
  3826. include Persona
  3827.  
  3828. attr_accessor :shuffle_result
  3829. alias persona_shuffle_init initialize
  3830. def initialize
  3831. persona_shuffle_init
  3832. @shuffle_result = nil
  3833. end
  3834.  
  3835. def reset_shuffle_result
  3836. @shuffle_result = nil
  3837. end
  3838.  
  3839. def shuffle_time
  3840. SceneManager.call(Scene_Shuffle)
  3841. Fiber.yield
  3842. end
  3843.  
  3844. def filter_cards(cards)
  3845. if !ALLOW_DUPLICATES
  3846. blanks = cards.count("Blank")
  3847. penalties = cards.count("Penalty")
  3848. # keep unique cards except blank and penalty
  3849. cards = cards.uniq.select{|c| ["Blank", "Penalty"].index(c).nil? }
  3850. # add blanks and penalties back
  3851. cards += (["Blank"] * blanks + ["Penalty"] * penalties)
  3852. end
  3853.  
  3854. if cards.uniq.sort == ["Blank", "Penalty"] || cards.empty?
  3855. # if there are only blank and penalty cards then just empty the
  3856. # list and return, so that there is no shuffle time
  3857. return []
  3858. elsif cards.select{|c| c != "Blank" || c != "Penalty"}.length < MIN_CARDS_TO_SHUFFLE
  3859. return []
  3860. end
  3861.  
  3862. # count penalty and blank cards dropped
  3863. penalty_cnt = cards.count("Penalty")
  3864. blank_cnt = cards.count("Blank")
  3865.  
  3866. # check for min and max penalty/blank cards and "fix" the number
  3867.  
  3868. if penalty_cnt < MIN_PENALTY_CARDS
  3869. (MIN_PENALTY_CARDS - penalty_cnt).times{ cards.push("Penalty") }
  3870. elsif penalty_cnt > MAX_PENALTY_CARDS
  3871. cards.delet("Penalty")
  3872. MAX_PENALTY_CARDS.times{ cards.push("Penalty") }
  3873. end
  3874.  
  3875. if penalty_cnt < MIN_BLANK_CARDS
  3876. (MIN_BLANK_CARDS - penalty_cnt).times{ cards.push("Blank") }
  3877. elsif penalty_cnt > MAX_BLANK_CARDS
  3878. cards.delet("Blank")
  3879. MAX_BLANK_CARDS.times{ cards.push("Blank") }
  3880. end
  3881. return cards.shuffle
  3882. end
  3883. end
  3884.  
  3885. class Game_Troop < Game_Unit
  3886. def make_drop_cards
  3887. dead_members.inject([]) {|r, enemy| r += enemy.make_drop_cards }
  3888. end
  3889. end
  3890.  
  3891. class Window_AcceptShuffle < Window_Command
  3892. include Persona
  3893.  
  3894. def initialize
  3895. clear_command_list
  3896. make_command_list
  3897. x, y = get_window_position
  3898. super(x, y)
  3899. self.z = 250
  3900. self.openness = 0
  3901. refresh
  3902. select(0)
  3903. activate
  3904. end
  3905.  
  3906. def get_window_position
  3907. case WINDOW_POSITIONS[ACCEPT_POSITION]
  3908. when "BL"
  3909. x = 0
  3910. y = Graphics.height - window_height
  3911. when "BR"
  3912. x = Graphics.width - window_width
  3913. y = Graphics.height - window_height
  3914. when "TL"
  3915. x = 0
  3916. y = 0
  3917. when "TR"
  3918. x = Graphics.width - window_width
  3919. y = 0
  3920. end
  3921. return x, y
  3922. end
  3923.  
  3924. def update_open
  3925. self.openness += 16
  3926. @opening = false if open?
  3927. end
  3928.  
  3929. def visible_line_number
  3930. 2
  3931. end
  3932.  
  3933. def make_command_list
  3934. add_command("Accept", :accept, true)
  3935. add_command("Decline", :decline, true)
  3936. end
  3937. end
  3938.  
  3939. class Window_MatchCounter < Window_Base
  3940. include Persona
  3941. def initialize(max_tries)
  3942. @max_tries = max_tries
  3943. @tries_left = max_tries + 1
  3944. height = fitting_height(1)
  3945. x, y = get_window_position
  3946. super(x, y, window_width, window_height)
  3947. self.z = 250
  3948. self.openness = 0
  3949. tried
  3950. end
  3951.  
  3952. def get_window_position
  3953. case WINDOW_POSITIONS[ACCEPT_POSITION]
  3954. when "BL"
  3955. x = 0
  3956. y = Graphics.height - window_height
  3957. when "BR"
  3958. x = Graphics.width - window_width
  3959. y = Graphics.height - window_height
  3960. when "TL"
  3961. x = 0
  3962. y = 0
  3963. when "TR"
  3964. x = Graphics.width - window_width
  3965. y = 0
  3966. end
  3967. return x, y
  3968. end
  3969.  
  3970. def window_width
  3971. 180
  3972. end
  3973.  
  3974. def window_height
  3975. fitting_height(1)
  3976. end
  3977.  
  3978. def tried
  3979. @tries_left -= 1
  3980. txt = "Tries left: #{@tries_left}/#{@max_tries}"
  3981. contents.clear
  3982. draw_text(0, 0, self.width - standard_padding, line_height, txt)
  3983. end
  3984.  
  3985. def lost?
  3986. return @tries_left == 0
  3987. end
  3988. end
  3989.  
  3990. class Window_ShuffleMessage < Window_Message
  3991. def update_fiber
  3992. if @fiber
  3993. @fiber.resume
  3994. elsif $game_message.shuffle_busy? && !$game_message.scroll_mode
  3995. @fiber = Fiber.new { fiber_main }
  3996. @fiber.resume
  3997. else
  3998. $game_message.visible = false
  3999. end
  4000. end
  4001.  
  4002. def fiber_main
  4003. $game_message.visible = true
  4004. update_background
  4005. update_placement
  4006. loop do
  4007. process_all_text if $game_message.shuffle_has_text?
  4008. process_input
  4009. $game_message.shuffle_clear
  4010. @gold_window.close
  4011. Fiber.yield
  4012. break unless text_continue?
  4013. end
  4014. close_and_wait
  4015. $game_message.visible = false
  4016. @fiber = nil
  4017. end
  4018.  
  4019. def process_all_text
  4020. open_and_wait
  4021. text = convert_escape_characters($game_message.shuffle_all_text)
  4022. pos = {}
  4023. new_page(text, pos)
  4024. process_character(text.slice!(0, 1), text, pos) until text.empty?
  4025. end
  4026.  
  4027. def text_continue?
  4028. $game_message.shuffle_has_text? && !settings_changed?
  4029. end
  4030.  
  4031. def new_page(text, pos)
  4032. contents.clear
  4033. reset_font_settings
  4034. pos[:x] = 0
  4035. pos[:y] = 0
  4036. pos[:new_x] = 0
  4037. pos[:height] = calc_line_height(text)
  4038. clear_flags
  4039. end
  4040. end
  4041.  
  4042. class Scene_Shuffle < Scene_Base
  4043. include Persona
  4044.  
  4045. def start
  4046. super
  4047. create_attributes
  4048. create_acceptance_window
  4049. create_counter_window
  4050. create_background
  4051. create_paths
  4052. start_cards_appear
  4053. setup_music
  4054. end
  4055.  
  4056. def terminate
  4057. super
  4058. @cards.each{|c| c.dispose}
  4059. @background_sprite.dispose
  4060. end
  4061.  
  4062. def start_cards_appear
  4063. @cards.each{ |card| card.start_effect(:appear)}
  4064. end
  4065.  
  4066. def setup_music
  4067. @last_bgm = RPG::BGM.last
  4068. @last_bgs = RPG::BGS.last
  4069.  
  4070. Audio.bgm_play(*SHUFFLE_BGM) if !SHUFFLE_BGM.nil?
  4071. Audio.bgs_play(*SHUFFLE_BGS) if !SHUFFLE_BGS.nil?
  4072. end
  4073.  
  4074. def create_attributes
  4075. get_cards
  4076. # center of screen
  4077. @cx = (Graphics.width / 2).to_i
  4078. @cy = (Graphics.height / 2).to_i
  4079.  
  4080. # dimensions of the cards
  4081. card_bitmap = Cache.card("Blank")
  4082. @card_width = card_bitmap.width
  4083. @card_height = card_bitmap.height
  4084.  
  4085. # result of shuffle
  4086. @card_selected = nil
  4087.  
  4088. @message_window = Window_ShuffleMessage.new
  4089. @counter_window = nil
  4090.  
  4091. # determine shuffle method from variable or other
  4092. if $game_variables[FORCE_SHUFFLE_METHOD_VAR_ID] == 0
  4093. @shuffle_method = Persona.SHUFFLE_SELECTION(@cards)
  4094. else
  4095. @shuffle_method = $game_variables[FORCE_SHUFFLE_METHOD_VAR_ID]
  4096. $game_variables[FORCE_SHUFFLE_METHOD_VAR_ID] = 0
  4097. end
  4098. # current phase of the shuffle time process
  4099. @shuffle_phase = "Show"
  4100. @shuffle_paths = []
  4101.  
  4102. @cursor_index = 0
  4103. end
  4104.  
  4105. def get_cards
  4106. card_items = BattleManager.cards_dropped
  4107. if $game_variables[SHUFFLE_ITEMS_VAR_ID] != 0
  4108. card_items = $game_variables[SHUFFLE_ITEMS_VAR_ID]
  4109. $game_variables[SHUFFLE_ITEMS_VAR_ID] = nil
  4110. card_items = $game_system.filter_cards(card_items) if FILTER_MANUAL_CARDS
  4111. else
  4112. card_items = BattleManager.cards_dropped
  4113. end
  4114.  
  4115. if card_items.nil? || card_items == 0
  4116. msgbox("No cards were defined in variable with id #{SHUFFLE_ITEMS_VAR_ID} for the shuffle time!")
  4117. cancel_shuffle
  4118. return
  4119. end
  4120.  
  4121. @cards = card_items.collect{|c| Sprite_Card.new(@viewport, c) }
  4122. end
  4123.  
  4124. def create_acceptance_window
  4125. @acceptance_window = Window_AcceptShuffle.new
  4126. @acceptance_window.set_handler(:accept, method(:start_shuffle_time))
  4127. @acceptance_window.set_handler(:cancel, method(:cancel_shuffle))
  4128. @acceptance_window.open
  4129. end
  4130.  
  4131. def create_counter_window
  4132. @counter_window = Window_MatchCounter.new(MATCHING_TRIES)
  4133. end
  4134.  
  4135. def start_shuffle_time
  4136. @acceptance_window.close
  4137. if @shuffle_method == "Matching"
  4138. start_matching
  4139. else
  4140. start_shuffle
  4141. end
  4142. end
  4143.  
  4144. def start_shuffle
  4145. @cards.each_with_index do |card, i|
  4146. x1 = card.x
  4147. y1 = card.y
  4148. x2 = @shuffle_paths[i][0][0]
  4149. y2 = @shuffle_paths[i][0][1]
  4150. # basically makes the card wait some frames before it goes to the
  4151. # shuffle path. all cards go one by one
  4152. wait = []
  4153. (@shuffle_paths[0].size / @cards.size * i).times do |i|
  4154. wait.push([x1, y1])
  4155. end
  4156. # appends to the wait list the intermediate points between the current
  4157. # position of the card and the starting position in the shuffle path
  4158. card.current_path = wait + get_intermediate_points(x1, y1, x2, y2)
  4159. card.repeat_path = false
  4160. card.start_effect(:flip) # make the card flip face down
  4161. end
  4162.  
  4163. @shuffle_phase = "Shuffle"
  4164. # calculate all x,y indexes of the cards. used only for up and down movement
  4165. # in matching shuffle method
  4166. @card_indexes = @cards.each_with_index.collect{|n, i| [i/MAX_CARDS_PER_ROW, i%MAX_CARDS_PER_ROW]}
  4167. end
  4168.  
  4169. def start_matching
  4170. new_cards = []
  4171.  
  4172. # picks random cards and shows them for a short amount of frames
  4173. @cards.sample(@cards.size/2).each{ |c| c.tease=true }
  4174.  
  4175. # diplicates all the cards for the matching method
  4176. @cards.each{ |card| new_cards.push(Sprite_Card.new(@viewport, card.card)) }
  4177.  
  4178. # shuffles all the cards, appends them together and shuffles them again
  4179. @cards = @cards.shuffle + new_cards.shuffle
  4180. @cards.shuffle!
  4181.  
  4182. # max cards per row
  4183. max_cols = MAX_CARDS_PER_ROW
  4184. @cards.each_with_index do |card, i|
  4185. # at first make all the cards go to the center of the screen
  4186. x1 = card.x
  4187. y1 = card.y
  4188. x2 = @cx - @card_width / 2
  4189. y2 = @cy - @card_height / 2
  4190. travel1 = get_intermediate_points(x1, y1, x2, y2)
  4191.  
  4192. # make them wait there for a second
  4193. wait = []
  4194. (Graphics.frame_rate).to_i.times do |i|
  4195. wait.push([x2, y2, 100])
  4196. end
  4197.  
  4198. x1 = @cx
  4199. y1 = @cy
  4200. # calculate their position in the matching process
  4201. x2, y2, z = show_position(i/max_cols, i%max_cols, max_cols)
  4202. # create path to that position
  4203. travel2 = get_intermediate_points(x1, y1, x2, y2)
  4204.  
  4205. # add the path to the card's path
  4206. card.current_path = travel1 + wait + travel2
  4207. # card does not loop this path
  4208. card.repeat_path = false
  4209. # flips them while they go to the center of the screen
  4210. card.start_effect(:flip)
  4211. end
  4212.  
  4213. @counter_window.open
  4214. # calculate all x,y indexes of the cards. used only for up and down movement
  4215. # in matching shuffle method
  4216. @card_indexes = @cards.each_with_index.collect{|n, i| [i/MAX_CARDS_PER_ROW, i%MAX_CARDS_PER_ROW]}
  4217. end
  4218.  
  4219. def cancel_shuffle
  4220. @last_bgm.replay
  4221. @last_bgs.replay
  4222. SceneManager.return
  4223. end
  4224.  
  4225. def create_background
  4226. @background_sprite = Sprite.new
  4227. if SHUFFLE_BACKGROUND
  4228. @background_sprite.bitmap = Cache.load_bitmap("Graphics/Persona/", SHUFFLE_BACKGROUND)
  4229. else
  4230. @background_sprite.bitmap = SceneManager.background_bitmap
  4231. end
  4232. end
  4233.  
  4234. def update
  4235. super
  4236. update_cards
  4237. determine_loss_matching if @shuffle_method == "Matching"
  4238. process_input if !teasing_phase
  4239. end
  4240.  
  4241. def update_all_windows
  4242. @acceptance_window.update
  4243. @counter_window.update
  4244. end
  4245.  
  4246. def determine_loss_matching
  4247. if @counter_window.lost?
  4248. @counter_window.close
  4249. @message_window.z = 250
  4250. $game_message.shuffle_add(MATCHING_LOSE_MESSAGE)
  4251. wait_for_message
  4252. SceneManager.return
  4253. finish_shuffle
  4254. end
  4255. end
  4256.  
  4257. def update_for_matched
  4258. Graphics.update
  4259. Input.update
  4260.  
  4261. $game_timer.update
  4262. update_matches
  4263. end
  4264.  
  4265. def update_matches
  4266. @cards.each{ |c| c.update }
  4267. end
  4268.  
  4269. def update_for_wait
  4270. Graphics.update
  4271. Input.update
  4272.  
  4273. $game_timer.update
  4274. @message_window.update
  4275. @counter_window.update if @counter_window
  4276. if @card_selected
  4277. update_selected_card
  4278. update_other_cards
  4279. end
  4280. end
  4281.  
  4282. def wait_for_message
  4283. @message_window.update
  4284. update_for_wait while $game_message.visible
  4285. end
  4286.  
  4287. def update_selected_card
  4288. @card_selected.update
  4289. end
  4290.  
  4291. def update_other_cards
  4292. @cards.each do |card|
  4293. next if card == @card_selected
  4294. card.update
  4295. end
  4296. end
  4297.  
  4298. def update_cards
  4299. @cards.each_with_index do |card, i|
  4300. card.update
  4301.  
  4302. # if it's a shuffle method, set its path in the shuffling and
  4303. # make it repeat it
  4304. if @shuffle_phase == "Shuffle"
  4305. if card.path_indx == card.current_path.size - 1 && !card.repeat_path
  4306. # if the card has reached its destination in the shuffle path
  4307. card.current_path = @shuffle_paths[i]
  4308. card.repeat_path = true
  4309. end
  4310. end
  4311. end
  4312. end
  4313.  
  4314. def teasing_phase
  4315. @cards.select{|c| c.teasing? }.length > 0
  4316. end
  4317.  
  4318. def cards_done_moving
  4319. @cards.inject(true){ |done, c| done && c.done_moving }
  4320. end
  4321.  
  4322. def process_input
  4323. # if last card is repeating its path then it has entered the shuffle loop
  4324. # therefore we accept input for selection
  4325. process_input_shuffle if @shuffle_phase == "Shuffle" && Input.trigger?(:C) && @cards[-1].repeat_path
  4326. process_input_matching if @shuffle_method == "Matching" && cards_done_moving
  4327. end
  4328.  
  4329. def process_input_shuffle
  4330. @shuffle_phase = "Selected"
  4331. # card selected is the one with the shortest distance between the
  4332. # center of the screen, with z value that of the max z value of the
  4333. # path the cards are following (is closer to the "screen")
  4334. Sound.play_ok
  4335. z = @cards[0].current_path.max_by{|coords| coords[2] }[2]
  4336. @card_selected = @cards.min_by{ |card| Math.sqrt((@cx - card.cx)**2 + (@cy - card.cy)**2 + (z - card.z)**2) }
  4337. show_selected_card
  4338.  
  4339. for card in @cards
  4340. next if card == @card_selected
  4341. card.start_effect(:disappear)
  4342. end
  4343.  
  4344. @card_selected.start_effect(:flip)
  4345. finish_shuffle
  4346. end
  4347.  
  4348. def process_input_matching
  4349. if @cards.inject(false){|done, c| done || c.tease }
  4350. # runs only once to quickly the cards that will be teased
  4351. @cards.each{|c| c.start_effect(:tease) if c.tease }
  4352. end
  4353.  
  4354. process_movement_input
  4355.  
  4356. if !@cards[@cursor_index].teasing? && !@cards[@cursor_index].flipping?
  4357. # if the current card is not being teased and is not being flipped
  4358. # then flash the card with red colour (meaning the cursor is on that
  4359. # card)
  4360. @cards[@cursor_index].start_effect(:matching_selected)
  4361. end
  4362.  
  4363. if Input.trigger?(:C) && !@cards[@cursor_index].match_selected?
  4364. Sound.play_ok
  4365.  
  4366. @cards[@cursor_index].revert_to_normal
  4367. # flip (show) selected card
  4368. @cards[@cursor_index].start_effect(:flip)
  4369. @cards[@cursor_index].match_selected = true
  4370.  
  4371. selected_cards = @cards.select{ |c| c.match_selected? }
  4372. if selected_cards.length == 2
  4373. # show cards for half a second
  4374. (Graphics.frame_rate / 2).to_i.times{ |i| update_for_matched }
  4375.  
  4376. if selected_cards[0].card != "Blank" && selected_cards[0].card == selected_cards[1].card
  4377. # keep selected cards face up and disappear all other
  4378. @cards.each{|c| c.start_effect(:disappear) if !c.match_selected? }
  4379. selected_cards[1].start_effect(:disappear)
  4380.  
  4381. @card_selected = selected_cards[0]
  4382. @counter_window.close
  4383. show_selected_card
  4384.  
  4385. finish_shuffle
  4386. else
  4387. Sound.play_cancel
  4388. @counter_window.tried
  4389. end
  4390.  
  4391. selected_cards.each do |c|
  4392. c.match_selected = false
  4393. c.start_effect(:flip)
  4394. end
  4395. end
  4396. end
  4397. end
  4398.  
  4399. def process_movement_input
  4400. # calculate x,y of current index
  4401. index = [@cursor_index/MAX_CARDS_PER_ROW, @cursor_index%MAX_CARDS_PER_ROW]
  4402. if Input.trigger?(:UP)
  4403. Sound.play_cursor
  4404. @cards[@cursor_index].revert_to_normal
  4405.  
  4406. # make row change more "natural"
  4407. index[0] -= 1 # previous row
  4408. # if it was first row and pressed up, go to last row
  4409. index[0] = @card_indexes[-1][0] if index[0] < 0
  4410. # if went from one row to another with different number of cards
  4411. # fix x index being more than the number of cards of that row
  4412. index[1] = @card_indexes[-1][1] if index[1] > @card_indexes[-1][1]
  4413. prev_card_x = @cards[@cursor_index].x
  4414. new_indx = index[0]*MAX_CARDS_PER_ROW + index[1]
  4415. # get all cards of new row
  4416. new_row_cards = @cards.select{|c| c.y == @cards[new_indx].y}
  4417. # get index of card in the new row with the closest x position as the
  4418. # last one
  4419. new_card = new_row_cards.each_with_index.min_by{|c, i| (c.x - prev_card_x).abs}[1]
  4420. # calculate new index in list of all cards
  4421. @cursor_index = new_card + index[0] * MAX_CARDS_PER_ROW
  4422. elsif Input.trigger?(:RIGHT)
  4423. Sound.play_cursor
  4424. @cards[@cursor_index].revert_to_normal
  4425.  
  4426. @cursor_index += 1
  4427. @cursor_index = 0 if @cursor_index > @cards.length - 1
  4428. elsif Input.trigger?(:DOWN)
  4429. Sound.play_cursor
  4430. @cards[@cursor_index].revert_to_normal
  4431.  
  4432. # same concept with :UP
  4433. index[0] += 1
  4434. index[0] = @card_indexes[0][0] if index[0] > @card_indexes[-1][0]
  4435. index[1] = @card_indexes[-1][1] if index[1] > @card_indexes[-1][1]
  4436. prev_card_x = @cards[@cursor_index].x
  4437. new_indx = index[0]*MAX_CARDS_PER_ROW + index[1]
  4438. new_row_cards = @cards.select{|c| c.y == @cards[new_indx].y}
  4439. new_card = new_row_cards.each_with_index.min_by{|c, i| (c.x - prev_card_x).abs}[1]
  4440. @cursor_index = new_card + index[0] * MAX_CARDS_PER_ROW
  4441. elsif Input.trigger?(:LEFT)
  4442. Sound.play_cursor
  4443. @cards[@cursor_index].revert_to_normal
  4444.  
  4445. @cursor_index -= 1
  4446. @cursor_index = @cards.length - 1 if @cursor_index < 0
  4447. end
  4448. end
  4449.  
  4450. def show_selected_card
  4451. x1 = @card_selected.x
  4452. y1 = @card_selected.y
  4453. x2 = @cx - @card_width / 2
  4454. y2 = @cy - @card_height
  4455. @card_selected.current_path = get_intermediate_points(x1, y1, x2, y2)
  4456. @card_selected.repeat_path = false
  4457. @card_selected.z = 150
  4458. end
  4459.  
  4460. def finish_shuffle
  4461. if @card_selected.nil?
  4462. Audio.se_play(*SHUFFLE_BLANK_SOUND)
  4463. $game_message.shuffle_add(NO_CARD_DRAW_MSG)
  4464. wait_for_message
  4465. elsif @card_selected.card == "Blank"
  4466. Audio.se_play(*SHUFFLE_BLANK_SOUND)
  4467. $game_message.shuffle_add(BLANK_CARD_DRAW_MSG)
  4468. wait_for_message
  4469. elsif @card_selected.card == "Penalty"
  4470. Audio.se_play(*SHUFFLE_PENALTY_SOUND)
  4471. $game_message.shuffle_add(PENALTY_CARD_DRAW_MSG)
  4472. wait_for_message
  4473. elsif !@card_selected.nil?
  4474. Audio.se_play(*SHUFFLE_CARD_SOUND)
  4475. $game_message.shuffle_add(sprintf(PERSONA_CARD_DRAW_MSG, @card_selected.card))
  4476. wait_for_message
  4477.  
  4478. persona = $data_actors.find{ |p| !p.nil? && p.name == @card_selected.card }
  4479. $game_party.add_persona(persona.id)
  4480. end
  4481. @last_bgm.replay
  4482. @last_bgs.replay
  4483. $game_system.shuffle_result = @card_selected.nil? ? "" : @card_selected.card
  4484. SceneManager.return
  4485. Graphics.fadeout(30)
  4486. terminate
  4487. end
  4488.  
  4489. def create_main_viewport
  4490. @viewport = Viewport.new
  4491. @viewport.z = 200
  4492. end
  4493.  
  4494. def create_paths
  4495. @cards.each_with_index do |card, i|
  4496. max_cols = MAX_CARDS_PER_ROW
  4497. x, y, z = show_position(i/max_cols, i%max_cols, max_cols)
  4498. card.starting_position(x, y)
  4499. card.current_path = [[x, y, z]]
  4500. card.repeat_path = true
  4501. end
  4502. create_shuffle_paths
  4503. end
  4504.  
  4505. def show_position(i, j, max_cols=MAX_CARDS_PER_ROW)
  4506. # number of cards on current row
  4507. row_cards = [max_cols, @cards.size - (i*max_cols)].min
  4508. # calculate y depending on the current row
  4509. y = (Graphics.height - @card_height * (@cards.size / max_cols + 1))/2 + i * @card_height
  4510. # calculate starting x depending on the number of cards in current row
  4511. start_x = Graphics.width / 2 - (@card_width / 2) * row_cards
  4512.  
  4513. # calculate x depending on width of card
  4514. x = start_x + @card_width * j
  4515. return x, y, 100
  4516. end
  4517.  
  4518. def get_intermediate_points(x1, y1, x2, y2)
  4519. dist_x = (x1 - x2).abs
  4520. dist_y = (y1 - y2).abs
  4521. up_x = x1 > x2 ? -1 : 1 # if card has to go to the right or left
  4522. up_y = y1 > y2 ? -1 : 1 # if card has to go upwards of downwards
  4523. total_pos = 15
  4524. xs = [*0..total_pos].collect{ |i| x1 + (i * up_x) * dist_x/total_pos}
  4525. ys = [*0..total_pos].collect{ |i| y1 + (i * up_y) * dist_y/total_pos}
  4526. movement_path = xs.zip(ys)
  4527. return movement_path
  4528. end
  4529.  
  4530. def create_shuffle_paths
  4531. case @shuffle_method
  4532. when "Horizontal"
  4533. @cards.size.times do |i|
  4534. @shuffle_paths.push(calculate_horizontal_path)
  4535. end
  4536. when "Diagonal"
  4537. @cards.size.times do |i|
  4538. if i % 2 == 0
  4539. @shuffle_paths.push(calculate_diagonal_path)
  4540. else
  4541. @shuffle_paths.push(calculate_diagonal_path(true))
  4542. end
  4543. end
  4544. when "Combination"
  4545. @cards.size.times do |i|
  4546. if i % 2 == 0
  4547. @shuffle_paths.push(calculate_horizontal_path)
  4548. else
  4549. @shuffle_paths.push(calculate_diagonal_path(rand > 0.5))
  4550. end
  4551. end
  4552. end
  4553. end
  4554.  
  4555. def calculate_horizontal_path
  4556. movement_path = []
  4557. xs = []
  4558. ys = []
  4559.  
  4560. sx = @card_width / 3 # left-most position
  4561. ex = Graphics.width - (@card_width + @card_width/4) # right-most position
  4562. sy = (Graphics.height - @card_height) / 2 # top-most position
  4563. width = ex - sx
  4564. total_distance = width * 2
  4565. # will take one second to make a full loop
  4566. step = (total_distance / Graphics.frame_rate)
  4567. xs = []
  4568. for i in (sx...ex).step(step)
  4569. xs.push(i)
  4570. end
  4571. xs = xs + xs.reverse
  4572.  
  4573. y_step = 3
  4574. z_step = 3
  4575. # x positions are calculated, now calculate the y and z depending on the
  4576. # x position
  4577. xs.size.times do |i|
  4578. if i <= xs.size / 4 # last quarter of the round
  4579. x = xs[i]
  4580. y = sy + i * y_step
  4581. z = 100 + i * z_step # incease z (comes closer and becomes bigger)
  4582. movement_path.push([x, y, z])
  4583. elsif i <= 2 * xs.size / 4 # first
  4584. x = xs[i]
  4585. y = movement_path[i - 1][1] - y_step
  4586. # decrease z (goes further away and becomes smaller)
  4587. z = movement_path[i - 1][2] - z_step
  4588. movement_path.push([x, y, z])
  4589. elsif i <= 3 * xs.size / 4 # second
  4590. x = xs[i]
  4591. y = movement_path[i - 1][1] - y_step
  4592. z = movement_path[i - 1][2] - z_step
  4593. movement_path.push([x, y, z])
  4594. else # third
  4595. x = xs[i]
  4596. y = movement_path[i - 1][1] + y_step
  4597. z = movement_path[i - 1][2] + z_step
  4598. movement_path.push([x, y, z])
  4599. end
  4600. end
  4601. return movement_path
  4602. end
  4603.  
  4604. def calculate_diagonal_path(mirrored=false)
  4605. movement_path = []
  4606. xs = []
  4607. ys = []
  4608.  
  4609. # left-most position
  4610. sx = @card_width / 4
  4611. # right-most position
  4612. ex = Graphics.width - @card_width
  4613. width = ex - sx
  4614. total_distance = width * 2
  4615. # will take one second to make a full loop
  4616. step = (total_distance / Graphics.frame_rate)
  4617. for i in (sx...ex).step(step)
  4618. xs.push(i)
  4619. end
  4620. # if mirrored goes from right to left first
  4621. if mirrored
  4622. xs = xs.reverse + xs
  4623. else
  4624. # else from left to right first
  4625. xs = xs + xs.reverse
  4626. end
  4627.  
  4628. # top-most position
  4629. sy = 0
  4630. # bottom-most position
  4631. ey = Graphics.height - @card_height
  4632. height = ey - sy
  4633. total_distance = height * 2
  4634. # will take one second to make a full loop
  4635. step = (total_distance / Graphics.frame_rate)
  4636. for i in (sy...ey).step(step)
  4637. ys.push(i)
  4638. end
  4639. ys = ys + ys.reverse
  4640.  
  4641. y_step = 3
  4642. z_step = 3
  4643. xs.size.times do |i|
  4644. if i <= xs.size / 4 # last quarter of loop
  4645. x = xs[i]
  4646. z = 100 + i * z_step
  4647. movement_path.push([x, ys[i], z])
  4648. elsif i <= 2 * xs.size / 4 # first
  4649. x = xs[i]
  4650. z = movement_path[i - 1][2] - z_step
  4651. movement_path.push([x, ys[i], z])
  4652. elsif i <= 3 * xs.size / 4 # second
  4653. x = xs[i]
  4654. z = movement_path[i - 1][2] - z_step
  4655. movement_path.push([x, ys[i], z])
  4656. else # last
  4657. x = xs[i]
  4658. z = movement_path[i - 1][2] + z_step
  4659. movement_path.push([x, ys[i], z])
  4660. end
  4661. end
  4662. return movement_path
  4663. end
  4664. end