Guest User

Blizz ABS Part 2 (edited)

a guest
Jan 18th, 2013
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 372.43 KB | None | 0 0
  1. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
  2. # Blizz-ABS by Blizzard and winkio
  3. # Version: 2.84
  4. # Type: Advanced Action Battle System
  5. # Date v1.00: 19.04.2007
  6. # Date v1.01: 30.04.2007
  7. # Date v1.02: 17.07.2007
  8. # Date v1.04: 25.07.2007
  9. # Date v1.09: 25.07.2007
  10. # Date v1.20: 29.07.2007
  11. # Date v1.23: 30.07.2007
  12. # Date v1.24: 5.08.2007
  13. # Date v1.60: 5.09.2007
  14. # Date v1.61: 6.09.2007
  15. # Date v1.62: 7.09.2007
  16. # Date v1.63: 11.09.2007
  17. # Date v1.64: 11.09.2007
  18. # Date v1.65: 12.09.2007
  19. # Date v1.66: 10.10.2007
  20. # Date v1.67: 16.10.2007
  21. # Date v1.69: 31.10.2007
  22. # Date v1.70: 13.11.2007
  23. # Date v1.71: 22.11.2007
  24. # Date v1.72: 10.12.2007
  25. # Date v1.73: 11.12.2007
  26. # Date v1.80: 18.12.2007
  27. # Date v1.89: 13.01.2008
  28. # Date v1.95: 29.02.2008
  29. # Date v1.96: 5.03.2008
  30. # Date v1.97: 28.03.2008
  31. # Date v1.98: 5.04.2008
  32. # Date v1.99: 4.08.2008
  33. # Date v2.00: 1.12.2008
  34. # Date v2.01: 1.12.2008
  35. # Date v2.02: 2.12.2008
  36. # Date v2.03: 3.12.2008
  37. # Date v2.10: 4.12.2008
  38. # Date v2.11: 5.12.2008
  39. # Date v2.12: 5.12.2008
  40. # Date v2.13: 6.12.2008
  41. # Date v2.14: 7.12.2008
  42. # Date v2.15: 8.12.2008
  43. # Date v2.20: 13.12.2008
  44. # Date v2.21: 19.12.2008
  45. # Date v2.22: 08.01.2009
  46. # Date v2.23: 25.01.2009
  47. # Date v2.30: 8.04.2009
  48. # Date v2.31: 8.04.2009
  49. # Date v2.50: 20.04.2009
  50. # Date v2.51: 20.04.2009
  51. # Date v2.52: 20.04.2009
  52. # Date v2.53: 2.05.2009
  53. # Date v2.54: 23.05.2009
  54. # Date v2.55: 28.06.2009
  55. # Date v2.56: 29.07.2009
  56. # Date v2.57: 19.08.2009
  57. # Date v2.60: 27.11.2009
  58. # Date v2.70: 28.11.2009
  59. # Date v2.71: 12.5.2010
  60. # Date v2.74: 16.5.2010
  61. # Date v2.79: 20.5.2010
  62. # Date v2.80: 4.6.2010
  63. # Date v2.81: 6.1.2011
  64. # Date v2.82: 7.1.2011
  65. # Date v2.83: 19.1.2011
  66. # Date v2.84: 23.1.2011
  67. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
  68. #
  69. # PART 2
  70. #
  71. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
  72. #
  73. # This work is protected by the following license:
  74. # #----------------------------------------------------------------------------
  75. # #
  76. # # Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
  77. # # ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
  78. # #
  79. # # You are free:
  80. # #
  81. # # to Share - to copy, distribute and transmit the work
  82. # # to Remix - to adapt the work
  83. # #
  84. # # Under the following conditions:
  85. # #
  86. # # Attribution. You must attribute the work in the manner specified by the
  87. # # author or licensor (but not in any way that suggests that they endorse you
  88. # # or your use of the work).
  89. # #
  90. # # Noncommercial. You may not use this work for commercial purposes.
  91. # #
  92. # # Share alike. If you alter, transform, or build upon this work, you may
  93. # # distribute the resulting work only under the same or similar license to
  94. # # this one.
  95. # #
  96. # # - For any reuse or distribution, you must make clear to others the license
  97. # # terms of this work. The best way to do this is with a link to this web
  98. # # page.
  99. # #
  100. # # - Any of the above conditions can be waived if you get permission from the
  101. # # copyright holder.
  102. # #
  103. # # - Nothing in this license impairs or restricts the author's moral rights.
  104. # #
  105. # #----------------------------------------------------------------------------
  106. #
  107. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
  108. #
  109. # Information:
  110. #
  111. # This script will allow you to create games with an Action Battle System
  112. # (ABS) (i.e. Zelda). Action Battle System means real time battle on the map.
  113. #
  114. # If you don't read the Manual, you will not be able to use many of the great
  115. # features this ABS supports.
  116. #
  117. # You DID NOT get the documentation with Blizz-ABS? Please contact me under
  118. # the URL provided below.
  119. #
  120. #
  121. # If you find any bugs, please report them here:
  122. # http://forum.chaos-project.com
  123. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
  124.  
  125. #==============================================================================
  126. # BlizzABS
  127. #------------------------------------------------------------------------------
  128. # This is the master control, configuration, utility and battle process
  129. # module for Blizz-ABS.
  130. #==============================================================================
  131.  
  132. module BlizzABS
  133.  
  134. # version of Blizz-ABS
  135. VERSION = 2.84
  136. # edition of Blizz-ABS
  137. EDITION = 'Normal'
  138. # constants to help the user when using the special commands
  139. PARTY = false
  140. TROOP = false
  141. INCREASE = 0
  142. DECREASE = 1
  143. CONSTANT = 0
  144. VARIABLE = 1
  145. KILL = true
  146. NO_KILL = false
  147. ADD = true
  148. REMOVE = false
  149. ATTACK = 0
  150. DEFEND = 1
  151. ESCAPE = 2
  152. SKILL = 3
  153. ITEM = 4
  154. ENEMIES = true
  155. ACTORS = false
  156. NONE = nil
  157.  
  158. # action types
  159. ACTNone = 0
  160. ACTAttack = 1
  161. ACTDefend = 2
  162. ACTSkill = 3
  163. ACTItem = 4
  164.  
  165. # attack types
  166. SWORD = 1
  167. SPEAR = 2
  168. FLAIL = 3
  169. BOOMERANG = 4
  170. BOW = 5
  171. BOW_ARROW = 6
  172. SHURIKEN = 7
  173.  
  174. # special types
  175. SHOOT = 1
  176. HOMING = 2
  177. DIRECT = 3
  178. BEAM = 4
  179. TRAP = 5
  180. TIMED = 6
  181. SUMMON = 7
  182.  
  183. # explode types
  184. EXPLNone = 1
  185. EXPLTarget = 2
  186. EXPLEnd = 3
  187. EXPLAny = 4
  188.  
  189. # remote types
  190. REMReturning = 0
  191. REMOnReturn = 1
  192. REMNormal = 2
  193. REMShotItem = 3
  194. REMShotWeapon = 4
  195. REMNormalSkill = 5
  196. REMBreakSkill = 6
  197. REMInitSkill = 7
  198. REMHomingSkill = 8
  199. REMNormalItem = 9
  200. REMBreakItem = 10
  201. REMInitItem = 11
  202. REMHomingItem = 12
  203. REMTrapSkill = 13
  204. REMTrapItem = 14
  205. REMTimedSkill = 15
  206. REMTimedItem = 16
  207.  
  208. # remote groups
  209. REMRequest = [REMReturning, REMNormalSkill, REMBreakSkill, REMInitSkill,
  210. REMTrapSkill, REMNormalItem, REMBreakItem, REMHomingItem,
  211. REMTrapItem, REMTimedSkill, REMTimedItem]
  212. REMSkills = [REMNormalSkill, REMBreakSkill, REMInitSkill, REMHomingSkill,
  213. REMTrapSkill, REMTimedSkill]
  214. REMItems = [REMNormalItem, REMBreakItem, REMInitItem, REMHomingItem,
  215. REMTrapItem, REMTimedItem]
  216. REMPersistent = [REMReturning, REMOnReturn, REMBreakSkill, REMBreakItem]
  217. REMHomingBase = [REMInitSkill, REMHomingSkill, REMInitItem,
  218. REMHomingItem]
  219. REMHomingExtend = [REMOnReturn, REMInitSkill, REMHomingSkill,
  220. REMInitItem, REMHomingItem]
  221.  
  222. # charge types
  223. CHARGENone = 1
  224. CHARGEFreeze = 2
  225. CHARGEMove = 3
  226. CHARGETrigger = 4
  227.  
  228. # charge data
  229. CHARGEAttack = 0
  230. CHARGESkill = 1
  231. CHARGEItem = 2
  232.  
  233. # summon data
  234. SUMMONNone = 1
  235. SUMMONPet = 2
  236. SUMMONMonster = 3
  237.  
  238. # command types
  239. COMScript = 1
  240. COMWait = 2
  241. COMMove = 3
  242. COMTurn = 4
  243. COMJump = 5
  244. COMAttack = 6
  245. COMSkill = 7
  246. COMItem = 8
  247. COMDefend = 9
  248. COMCharacter = 10
  249. COMBattler = 11
  250. COMInput = 12
  251. COMVariable = 13
  252. COMCondition = 14
  253. COMFreeze = 15
  254. COMCompletion = 16
  255. COMGoTo = 17
  256. COMAbort = 18
  257.  
  258. # direction command types
  259. DIR90Right = 11
  260. DIR90Left = 12
  261. DIRForward = 13
  262. DIRBackward = 14
  263. DIRTowardPlayer = 15
  264. DIRAwayPlayer = 16
  265. DIRRandom4 = 17
  266. DIRRandom8 = 18
  267. DIR45Right = 19
  268. DIR45Left = 20
  269.  
  270. # character command types
  271. CHSpeed = 1
  272. CHFrequency = 2
  273. CHSprite = 3
  274. CHAnimation = 4
  275. CHFix = 5
  276. CHThrough = 6
  277. CHOnTop = 7
  278. CHOpacity = 8
  279.  
  280. # variable command types
  281. VARGame = 1
  282. VARCombo = 2
  283. VARCharacter = 3
  284. VARParty = 4
  285. VARInput = 5
  286. VARConstant = 6
  287. VARScript = 7
  288.  
  289. # input trigger types
  290. INPress = 1
  291. INTrigger = 2
  292. INRelease = 3
  293.  
  294. # value command types
  295. VALHp = 1
  296. VALSp = 2
  297. VALMaxHp = 3
  298. VALMaxSp = 4
  299. VALState = 5
  300. VALExp = 6
  301. VALLevel = 7
  302. VALTile = 8
  303. VALDirection = 9
  304.  
  305. # trigger data
  306. TRGLeader = 0
  307. TRGAlly = 1
  308. TRGSelf = 2
  309. TRGEnemy = 3
  310. TRGProbability = 4
  311.  
  312. # trigger target data
  313. TRGTargetDefault = 0
  314. TRGTargetActivator = 1
  315.  
  316. # trigger condition data
  317. TRGHP = 0
  318. TRGSP = 1
  319. TRGState = 2
  320. TRGLocation = 3
  321.  
  322. # trigger comparison data
  323. TRGEqual = 0
  324. TRGNotEqual = 1
  325. TRGGreater = 2
  326. TRGGreaterEqual = 3
  327. TRGLess = 4
  328. TRGLessEqual = 5
  329.  
  330. # trigger action data
  331. TRGAttack = 0
  332. TRGDefend = 1
  333. TRGSkill = 2
  334. TRGItem = 3
  335.  
  336. # trigger location data
  337. TRGClosest = 0
  338. TRGFarthest = 1
  339.  
  340. # action data
  341. ACTNone = 0
  342. ACTAttack = 1
  343. ACTDefend = 2
  344. ACTEscape = 3
  345. ACTSkill = 4
  346. ACTItem = 5
  347.  
  348. # AI update data
  349. UPDLight = 1
  350. UPDMedium = 2
  351. UPDHeavy = 3
  352. UPDFull = 4
  353.  
  354. # custom event triggers
  355. CETNone = -1
  356. CETActionButton = 0
  357. CETPlayerTouch = 1
  358. CETEventTouch = 2
  359. CETDeath = 9
  360. CETWeapon = 21
  361. CETSkill = 22
  362. CETItem = 23
  363. CETEnemy = 24
  364. CETDefault = CETDeath
  365. CETSpecial = [CETWeapon, CETSkill, CETItem, CETEnemy]
  366.  
  367. # spriteset filenames
  368. SPRProjWeapon = 'projectile_weapon_'
  369. SPRProjSkill = 'projectile_skill_'
  370. SPRProjItem = 'projectile_item_'
  371. SPRProjEnemy = 'projectile_enemy_'
  372. SPRAttack = '_atk'
  373. SPRWeapon = '_wpn'
  374. SPRWeaponID = '_wpn_'
  375. SPRDefend = '_def'
  376. SPRSkill = '_skl'
  377. SPRItem = '_itm'
  378. SPRCharge = '_chr'
  379. SPRJumping = '_jmp'
  380. SPRRunning = '_run'
  381. SPRSneaking = '_snk'
  382. SPRIdle = '_idl'
  383. SPRCorpse = '_crp'
  384.  
  385. #============================================================================
  386. # BlizzABS::Cache
  387. #----------------------------------------------------------------------------
  388. # This class holds a few bitmaps so they don't need to be drawn each time
  389. # which improves speed and reduces lag. It also holds damage sprites and
  390. # remote characters. It also holds constant data that is used in Blizz-ABS
  391. # to improve the performance (i.e. creating arrays of data for processing).
  392. #============================================================================
  393.  
  394. class Cache
  395.  
  396. # constant cache
  397. LoopDir8 = [1, 2, 3, 6, 9, 8, 7, 4]
  398. Dir8 = [1, 2, 3, 4, 6, 7, 8, 9]
  399. Dir4 = [2, 4, 6, 8]
  400. NoDirsUpLeft = [1, 4, 7, 8, 9]
  401. NoDirsDownLeft = [1, 2, 3, 4, 7]
  402. NoDirsUpRight = [3, 6, 7, 8, 9]
  403. NoDirsDownRight = [1, 2, 3, 6, 9]
  404. NoDirsRight = [2, 3, 6, 8, 9]
  405. NoDirsLeft = [1, 2, 4, 8, 7]
  406. NoDirsDown = [1, 2, 3, 4, 6]
  407. NoDirsUp = [4, 6, 7, 8, 9]
  408. TDirs = [[0, true], [1, true], [2, true], [3, true], [4, true], [5, true],
  409. [6, true], [7, true], [8, true], [9, true]]
  410. FDirs = [[0, false], [1, false], [2, false], [3, false], [4, false],
  411. [5, false], [6, false], [7, false], [8, false], [9, false]]
  412. DirDownLeft = [2, 4]
  413. DirLeftDown = [4, 2]
  414. DirDownRight = [2, 6]
  415. DirRightDown = [6, 2]
  416. DirLeftUp = [4, 8]
  417. DirUpLeft = [8, 4]
  418. DirRightUp = [6, 8]
  419. DirUpRight = [8, 6]
  420. DirOffsets = [[0, 0], [-1, 1], [0, 1], [1, 1], [-1, 0], [0, 0], [1, 0],
  421. [-1, -1], [0, -1], [1, -1]]
  422. PathDirs = [[0, 1, 2], [-1, 0, 4], [1, 0, 6], [0, -1, 8]]
  423. Keys = 0..9
  424. HotkeyRange = 1..10
  425. PressTrigger = [0]
  426. TouchTrigger = [1, 2]
  427. BasicTrigger = [0, 1, 2]
  428. MapLayers = [2, 1, 0]
  429. ScopeOne = [1, 3, 5]
  430. HotKeys = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  431. EmptyKeys = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
  432. FramesDefault = [3, 3, 3, 3]
  433.  
  434. CommandsAIBehavior = ['Behavior', 'Next', 'Previous', 'Exit']
  435. CommandsAITrigger = ['Triggers', 'Next', 'Previous', 'Exit']
  436. CommandsTrigger = ['Edit', 'Add new', 'Delete', 'Copy', 'Move up',
  437. 'Move down', 'Exit']
  438. CommandsPreMenu = ['Menu', 'Hotkeys', 'AI Behavior', 'AI Triggers', 'Cancel']
  439. CommandsEdit = ['Activator', 'Condition', 'Comparison', 'Value',
  440. 'Action Type', 'Action', 'Target Type', 'Done', 'Cancel']
  441.  
  442. WORDAll = 'All'
  443. WORDState = 'State'
  444. WORDTarget = 'Target'
  445. WORDNormalState = 'Normal'
  446. WORDLocation = 'Location'
  447. WORDAggressive = 'Aggressive'
  448. WORDPassive = 'Passive'
  449. WORDOffensive = 'Offensive'
  450. WORDDefensive = 'Defensive'
  451.  
  452. TRGActivators = ['Leader', 'Ally', 'Self', 'Enemy', 'Probability']
  453. TRGTargets = ['Default', 'Activator']
  454. TRGComparators = ['==', '!=', '>', '>=', '<', '<=']
  455. TRGLocations = ['Closest', 'Farthest']
  456.  
  457. FontNameDamage = 'Arial Black'
  458. FontSizeDamage = 24
  459. FontItalicDamage = true
  460. FontBoldDamage = false
  461. TXTLvlUp = 'LvUp'
  462. TXTMiss = 'Miss'
  463. TXTDefend = load_data('Data/System.rxdata').words.guard
  464.  
  465. DMGColors = {}
  466. DMGColors[TXTLvlUp] = Color.new(192, 96, 255)
  467. DMGColors[TXTMiss] = Color.new(192, 192, 192)
  468. DMGColors[TXTDefend] = Color.new(192, 192, 192)
  469. DMGColors[0] = Color.new(192, 192, 192)
  470. DMGColors['Critical'] = Color.new(255, 0, 0)
  471. DMGColors['HP-A'] = Color.new(255, 192, 64)
  472. DMGColors['HP-E'] = Color.new(255, 0, 0)
  473. DMGColors['HP+A'] = Color.new(0, 192, 255)
  474. DMGColors['HP+E'] = Color.new(0, 192, 255)
  475. DMGColors['SP-A'] = Color.new(255, 255, 0)
  476. DMGColors['SP-E'] = Color.new(255, 255, 0)
  477. DMGColors['SP+A'] = Color.new(0, 255, 0)
  478. DMGColors['SP+E'] = Color.new(0, 255, 0)
  479. DMGColors['Default'] = Color.new(255, 255, 255)
  480. DMGColors['Shadow'] = Color.new(0, 0, 0)
  481.  
  482. # setting all accessible variables
  483. attr_reader :damages
  484. attr_reader :remotes
  485. attr_reader :beams
  486. #--------------------------------------------------------------------------
  487. # Initialization
  488. #--------------------------------------------------------------------------
  489. def initialize
  490. # initialize image, damage sprite, beam sprite and projectile buffers
  491. @data, @damages, @remotes, @beams = {}, [], [], []
  492. # add image
  493. @data['minimap_autotile'] = _minimap_autotile
  494. # prevent "Script is hanging" error
  495. Graphics.update
  496. # add image
  497. @data['menu_arrow'] = _menu_arrow
  498. # prevent "Script is hanging" error
  499. Graphics.update
  500. # add image
  501. @data['white_arrow'] = _white_arrow
  502. # prevent "Script is hanging" error
  503. Graphics.update
  504. # add image
  505. @data['green_arrow'] = _green_arrow
  506. # prevent "Script is hanging" error
  507. Graphics.update
  508. # add image
  509. @data['blue_arrow'] = @data['green_arrow'].clone
  510. # change color
  511. @data['blue_arrow'].hue_change(120)
  512. # add image
  513. @data['red_arrow'] = @data['green_arrow'].clone
  514. # change color
  515. @data['red_arrow'].hue_change(-120)
  516. # add image
  517. @data['yellow_arrow'] = @data['green_arrow'].clone
  518. # change color
  519. @data['yellow_arrow'].hue_change(-60)
  520. # add image
  521. @data['violet_arrow'] = @data['green_arrow'].clone
  522. # change color
  523. @data['violet_arrow'].hue_change(150)
  524. # prevent "Script is hanging" error
  525. Graphics.update
  526. # add image
  527. @data['empty_hud_white_bar'] = _empty_hud_white_bar
  528. # prevent "Script is hanging" error
  529. Graphics.update
  530. # add image
  531. @data['empty_hud_green_bar'] = _empty_hud_green_bar
  532. # prevent "Script is hanging" error
  533. Graphics.update
  534. # add image
  535. @data['empty_hud_blue_bar'] = @data['empty_hud_green_bar'].clone
  536. # change color
  537. @data['empty_hud_blue_bar'].hue_change(120)
  538. # add image
  539. @data['empty_hud_red_bar'] = @data['empty_hud_green_bar'].clone
  540. # change color
  541. @data['empty_hud_red_bar'].hue_change(-120)
  542. # prevent "Script is hanging" error
  543. Graphics.update
  544. # add image
  545. @data['hud_white_bar'] = _hud_white_bar
  546. # prevent "Script is hanging" error
  547. Graphics.update
  548. # add image
  549. @data['hud_green_bar'] = _hud_green_bar
  550. # prevent "Script is hanging" error
  551. Graphics.update
  552. # add image
  553. @data['hud_blue_bar'] = @data['hud_green_bar'].clone
  554. # change color
  555. @data['hud_blue_bar'].hue_change(120)
  556. # add image
  557. @data['hud_red_bar'] = @data['hud_green_bar'].clone
  558. # change color
  559. @data['hud_red_bar'].hue_change(-120)
  560. # prevent "Script is hanging" error
  561. Graphics.update
  562. # add image
  563. @data['empty_enemy_bar'] = _empty_enemy_bar
  564. # prevent "Script is hanging" error
  565. Graphics.update
  566. # add image
  567. @data['enemy_bar'] = _enemy_bar
  568. # prevent "Script is hanging" error
  569. Graphics.update
  570. # add image
  571. @data['beam1'] = _beam1
  572. # prevent "Script is hanging" error
  573. Graphics.update
  574. # add image
  575. @data['grid'] = _grid
  576. # prevent "Script is hanging" error
  577. Graphics.update
  578. end
  579. #--------------------------------------------------------------------------
  580. # clean
  581. # Cleans the cache from remotes and damage sprites.
  582. #--------------------------------------------------------------------------
  583. def clean
  584. # dispose all damage sprites
  585. @damages.each {|sprite| sprite.dispose if sprite.is_a?(Sprite)}
  586. # dispose all beam sprites
  587. @beams.each {|ary| ary[0].dispose}
  588. # create new damage sprite buffer and new projectile buffer
  589. @damages, @remotes, @beams = [], [], []
  590. # unfreeze all actor's actions
  591. $BlizzABS.battlers.each {|actor| actor.freeze_action = false}
  592. # clear observation and path request data
  593. $BlizzABS.AI = BlizzABS::AI.new
  594. end
  595. #--------------------------------------------------------------------------
  596. # image
  597. # key - hash key for the image
  598. # Returns a copy of the image.
  599. #--------------------------------------------------------------------------
  600. def image(key)
  601. return @data[key].clone
  602. end
  603. #--------------------------------------------------------------------------
  604. # _white_arrow
  605. # Creates the minimap icon for other events.
  606. #--------------------------------------------------------------------------
  607. def _white_arrow
  608. b = Bitmap.new(56, 14)
  609. c1 = Color.new(0, 0, 0)
  610. c2 = Color.new(255, 255, 255)
  611. b.set_pixel(23, 0, c1)
  612. b.set_pixel(32, 0, c1)
  613. b.set_pixel(22, 1, c1)
  614. b.fill_rect(23, 1, 1, 12, c2)
  615. b.fill_rect(24, 1, 1, 12, c1)
  616. b.fill_rect(31, 1, 1, 12, c1)
  617. b.fill_rect(32, 1, 1, 12, c2)
  618. b.set_pixel(33, 1, c1)
  619. b.set_pixel(21, 2, c1)
  620. b.fill_rect(22, 2, 1, 10, c2)
  621. b.fill_rect(33, 2, 1, 10, c2)
  622. b.set_pixel(34, 2, c1)
  623. b.fill_rect(1, 3, 12, 1, c1)
  624. b.set_pixel(20, 3, c1)
  625. b.fill_rect(21, 3, 1, 8, c2)
  626. b.fill_rect(34, 3, 1, 8, c2)
  627. b.set_pixel(35, 3, c1)
  628. b.fill_rect(48, 3, 2, 1, c1)
  629. b.set_pixel(0, 4, c1)
  630. b.fill_rect(1, 4, 12, 1, c2)
  631. b.set_pixel(13, 4, c1)
  632. b.set_pixel(19, 4, c1)
  633. b.fill_rect(20, 4, 1, 6, c2)
  634. b.fill_rect(35, 4, 1, 6, c2)
  635. b.set_pixel(36, 4, c1)
  636. b.set_pixel(47, 4, c1)
  637. b.fill_rect(48, 4, 2, 6, c2)
  638. b.set_pixel(50, 4, c1)
  639. b.set_pixel(1, 5, c1)
  640. b.fill_rect(2, 5, 10, 1, c2)
  641. b.set_pixel(12, 5, c1)
  642. b.set_pixel(18, 5, c1)
  643. b.fill_rect(19, 5, 1, 4, c2)
  644. b.fill_rect(36, 5, 1, 4, c2)
  645. b.set_pixel(37, 5, c1)
  646. b.set_pixel(46, 5, c1)
  647. b.fill_rect(47, 5, 1, 5, c2)
  648. b.fill_rect(50, 5, 1, 5, c2)
  649. b.set_pixel(51, 5, c1)
  650. b.set_pixel(2, 6, c1)
  651. b.fill_rect(3, 6, 8, 1, c2)
  652. b.set_pixel(11, 6, c1)
  653. b.fill_rect(17, 6, 1, 2, c1)
  654. b.fill_rect(18, 6, 1, 2, c2)
  655. b.fill_rect(37, 6, 1, 2, c2)
  656. b.fill_rect(38, 6, 1, 2, c1)
  657. b.set_pixel(45, 6, c1)
  658. b.fill_rect(46, 6, 1, 4, c2)
  659. b.fill_rect(51, 6, 1, 4, c2)
  660. b.set_pixel(52, 6, c1)
  661. b.set_pixel(3, 7, c1)
  662. b.fill_rect(4, 7, 6, 1, c2)
  663. b.set_pixel(10, 7, c1)
  664. b.set_pixel(44, 7, c1)
  665. b.fill_rect(45, 7, 1, 3, c2)
  666. b.fill_rect(52, 7, 1, 3, c2)
  667. b.set_pixel(53, 7, c1)
  668. b.set_pixel(4, 8, c1)
  669. b.fill_rect(5, 8, 4, 1, c2)
  670. b.set_pixel(9, 8, c1)
  671. b.set_pixel(18, 8, c1)
  672. b.set_pixel(37, 8, c1)
  673. b.set_pixel(43, 8, c1)
  674. b.fill_rect(44, 8, 1, 2, c2)
  675. b.fill_rect(53, 8, 1, 2, c2)
  676. b.set_pixel(54, 8, c1)
  677. b.set_pixel(5, 9, c1)
  678. b.fill_rect(6, 9, 2, 1, c2)
  679. b.set_pixel(8, 9, c1)
  680. b.set_pixel(19, 9, c1)
  681. b.set_pixel(36, 9, c1)
  682. b.set_pixel(42, 9, c1)
  683. b.set_pixel(43, 9, c2)
  684. b.set_pixel(54, 9, c2)
  685. b.set_pixel(55, 9, c1)
  686. b.fill_rect(6, 10, 2, 1, c1)
  687. b.set_pixel(20, 10, c1)
  688. b.set_pixel(35, 10, c1)
  689. b.fill_rect(43, 10, 12, 1, c1)
  690. b.set_pixel(21, 11, c1)
  691. b.set_pixel(34, 11, c1)
  692. b.set_pixel(22, 12, c1)
  693. b.set_pixel(33, 12, c1)
  694. b.set_pixel(23, 13, c1)
  695. b.set_pixel(32, 13, c1)
  696. return b
  697. end
  698. #--------------------------------------------------------------------------
  699. # _green_arrow
  700. # Creates the minimap icon for events.
  701. #--------------------------------------------------------------------------
  702. def _green_arrow
  703. b = Bitmap.new(56, 14)
  704. c1 = Color.new(0, 0, 0)
  705. c2 = Color.new(255, 255, 255)
  706. c3 = Color.new(0, 255, 0)
  707. b.set_pixel(23, 0, c1)
  708. b.set_pixel(32, 0, c1)
  709. b.set_pixel(22, 1, c1)
  710. b.fill_rect(23, 1, 1, 12, c3)
  711. b.fill_rect(24, 1, 1, 12, c1)
  712. b.fill_rect(31, 1, 1, 12, c1)
  713. b.fill_rect(32, 1, 1, 12, c3)
  714. b.set_pixel(33, 1, c1)
  715. b.set_pixel(21, 2, c1)
  716. b.fill_rect(22, 2, 1, 10, c3)
  717. b.fill_rect(33, 2, 1, 10, c3)
  718. b.set_pixel(34, 2, c1)
  719. b.fill_rect(1, 3, 12, 1, c1)
  720. b.set_pixel(20, 3, c1)
  721. b.fill_rect(21, 3, 1, 8, c3)
  722. b.fill_rect(34, 3, 1, 8, c3)
  723. b.set_pixel(35, 3, c1)
  724. b.fill_rect(48, 3, 2, 1, c1)
  725. b.set_pixel(0, 4, c1)
  726. b.fill_rect(1, 4, 12, 1, c3)
  727. b.set_pixel(13, 4, c1)
  728. b.set_pixel(19, 4, c1)
  729. b.fill_rect(20, 4, 1, 6, c3)
  730. b.fill_rect(35, 4, 1, 6, c3)
  731. b.set_pixel(36, 4, c1)
  732. b.set_pixel(47, 4, c1)
  733. b.fill_rect(48, 4, 2, 6, c3)
  734. b.set_pixel(50, 4, c1)
  735. b.set_pixel(1, 5, c1)
  736. b.fill_rect(2, 5, 10, 1, c3)
  737. b.set_pixel(12, 5, c1)
  738. b.set_pixel(18, 5, c1)
  739. b.fill_rect(19, 5, 1, 4, c3)
  740. b.fill_rect(36, 5, 1, 4, c3)
  741. b.set_pixel(37, 5, c1)
  742. b.set_pixel(46, 5, c1)
  743. b.fill_rect(47, 5, 1, 5, c3)
  744. b.fill_rect(50, 5, 1, 5, c3)
  745. b.set_pixel(51, 5, c1)
  746. b.set_pixel(2, 6, c1)
  747. b.fill_rect(3, 6, 8, 1, c3)
  748. b.set_pixel(11, 6, c1)
  749. b.fill_rect(17, 6, 1, 2, c1)
  750. b.fill_rect(18, 6, 1, 2, c3)
  751. b.fill_rect(37, 6, 1, 2, c3)
  752. b.fill_rect(38, 6, 1, 2, c1)
  753. b.set_pixel(45, 6, c1)
  754. b.fill_rect(46, 6, 1, 4, c3)
  755. b.fill_rect(51, 6, 1, 4, c3)
  756. b.set_pixel(52, 6, c1)
  757. b.set_pixel(3, 7, c1)
  758. b.fill_rect(4, 7, 6, 1, c3)
  759. b.set_pixel(10, 7, c1)
  760. b.set_pixel(44, 7, c1)
  761. b.fill_rect(45, 7, 1, 3, c3)
  762. b.fill_rect(52, 7, 1, 3, c3)
  763. b.set_pixel(53, 7, c1)
  764. b.set_pixel(4, 8, c1)
  765. b.fill_rect(5, 8, 4, 1, c3)
  766. b.set_pixel(9, 8, c1)
  767. b.set_pixel(18, 8, c1)
  768. b.set_pixel(37, 8, c1)
  769. b.set_pixel(43, 8, c1)
  770. b.fill_rect(44, 8, 1, 2, c3)
  771. b.fill_rect(53, 8, 1, 2, c3)
  772. b.set_pixel(54, 8, c1)
  773. b.set_pixel(5, 9, c1)
  774. b.fill_rect(6, 9, 2, 1, c3)
  775. b.set_pixel(8, 9, c1)
  776. b.set_pixel(19, 9, c1)
  777. b.set_pixel(36, 9, c1)
  778. b.set_pixel(42, 9, c1)
  779. b.set_pixel(43, 9, c3)
  780. b.set_pixel(54, 9, c3)
  781. b.set_pixel(55, 9, c1)
  782. b.fill_rect(6, 10, 2, 1, c1)
  783. b.set_pixel(20, 10, c1)
  784. b.set_pixel(35, 10, c1)
  785. b.fill_rect(43, 10, 12, 1, c1)
  786. b.set_pixel(21, 11, c1)
  787. b.set_pixel(34, 11, c1)
  788. b.set_pixel(22, 12, c1)
  789. b.set_pixel(33, 12, c1)
  790. b.set_pixel(23, 13, c1)
  791. b.set_pixel(32, 13, c1)
  792. return b
  793. end
  794. #--------------------------------------------------------------------------
  795. # _menu_arrow
  796. # Creates the arrow displayed in the hotkey assignment menu.
  797. #--------------------------------------------------------------------------
  798. def _menu_arrow
  799. b = Bitmap.new(16, 9)
  800. c1 = Color.new(0, 0, 0)
  801. c2 = Color.new(255, 255, 255)
  802. c3 = Color.new(127, 127, 127)
  803. b.fill_rect(7, 0, 2, 1, c2)
  804. b.set_pixel(6, 1, c2)
  805. b.fill_rect(7, 1, 1, 7, c3)
  806. b.fill_rect(8, 1, 1, 7, c1)
  807. b.set_pixel(9, 1, c2)
  808. b.set_pixel(5, 2, c2)
  809. b.fill_rect(6, 2, 1, 6, c3)
  810. b.fill_rect(9, 2, 1, 6, c1)
  811. b.set_pixel(10, 2, c2)
  812. b.set_pixel(4, 3, c2)
  813. b.fill_rect(5, 3, 1, 5, c3)
  814. b.fill_rect(10, 3, 1, 5, c1)
  815. b.set_pixel(11, 3, c2)
  816. b.set_pixel(3, 4, c2)
  817. b.fill_rect(4, 4, 1, 4, c3)
  818. b.fill_rect(11, 4, 1, 4, c1)
  819. b.set_pixel(12, 4, c2)
  820. b.set_pixel(2, 5, c2)
  821. b.fill_rect(3, 5, 1, 3, c3)
  822. b.fill_rect(12, 5, 1, 3, c1)
  823. b.set_pixel(13, 5, c2)
  824. b.set_pixel(1, 6, c2)
  825. b.fill_rect(2, 6, 1, 2, c3)
  826. b.fill_rect(13, 6, 1, 2, c1)
  827. b.set_pixel(14, 6, c2)
  828. b.set_pixel(0, 7, c2)
  829. b.set_pixel(1, 7, c3)
  830. b.set_pixel(14, 7, c1)
  831. b.set_pixel(15, 7, c2)
  832. b.fill_rect(1, 8, 14, 1, c2)
  833. return b
  834. end
  835. #--------------------------------------------------------------------------
  836. # _minimap_autotile
  837. # Creates the minimap autotile for passability.
  838. #--------------------------------------------------------------------------
  839. def _minimap_autotile
  840. b = Bitmap.new(24, 32)
  841. c1 = Color.new(191, 191, 191)
  842. c2 = Color.new(255, 255, 255)
  843. b.fill_rect(2, 0, 4, 1, c2)
  844. b.set_pixel(1, 1, c2)
  845. b.fill_rect(2, 1, 4, 6, c1)
  846. b.set_pixel(6, 1, c2)
  847. b.fill_rect(0, 2, 1, 4, c2)
  848. b.fill_rect(1, 2, 1, 4, c1)
  849. b.fill_rect(6, 2, 1, 4, c1)
  850. b.fill_rect(7, 2, 1, 4, c2)
  851. b.set_pixel(1, 6, c2)
  852. b.set_pixel(6, 6, c2)
  853. b.fill_rect(2, 7, 4, 1, c2)
  854. b.fill_rect(7, 8, 10, 1, c2)
  855. b.set_pixel(6, 9, c2)
  856. b.fill_rect(7, 9, 10, 22, c1)
  857. b.set_pixel(17, 9, c2)
  858. b.set_pixel(5, 10, c2)
  859. b.fill_rect(6, 10, 1, 20, c1)
  860. b.fill_rect(17, 10, 1, 20, c1)
  861. b.set_pixel(18, 10, c2)
  862. b.set_pixel(4, 11, c2)
  863. b.fill_rect(5, 11, 1, 18, c1)
  864. b.fill_rect(18, 11, 1, 18, c1)
  865. b.set_pixel(19, 11, c2)
  866. b.set_pixel(3, 12, c2)
  867. b.fill_rect(4, 12, 1, 16, c1)
  868. b.fill_rect(19, 12, 1, 16, c1)
  869. b.set_pixel(20, 12, c2)
  870. b.set_pixel(2, 13, c2)
  871. b.fill_rect(3, 13, 1, 14, c1)
  872. b.fill_rect(20, 13, 1, 14, c1)
  873. b.set_pixel(21, 13, c2)
  874. b.set_pixel(1, 14, c2)
  875. b.fill_rect(2, 14, 1, 12, c1)
  876. b.fill_rect(21, 14, 1, 12, c1)
  877. b.set_pixel(22, 14, c2)
  878. b.fill_rect(0, 15, 1, 10, c2)
  879. b.fill_rect(1, 15, 1, 10, c1)
  880. b.fill_rect(22, 15, 1, 10, c1)
  881. b.fill_rect(23, 15, 1, 10, c2)
  882. b.set_pixel(1, 25, c2)
  883. b.set_pixel(22, 25, c2)
  884. b.set_pixel(2, 26, c2)
  885. b.set_pixel(21, 26, c2)
  886. b.set_pixel(3, 27, c2)
  887. b.set_pixel(20, 27, c2)
  888. b.set_pixel(4, 28, c2)
  889. b.set_pixel(19, 28, c2)
  890. b.set_pixel(5, 29, c2)
  891. b.set_pixel(18, 29, c2)
  892. b.set_pixel(6, 30, c2)
  893. b.set_pixel(17, 30, c2)
  894. b.fill_rect(7, 31, 10, 1, c2)
  895. return b
  896. end
  897. #--------------------------------------------------------------------------
  898. # _empty_hud_white_bar
  899. # Creates the bitmap used for the empty HUD bars.
  900. #--------------------------------------------------------------------------
  901. def _empty_hud_white_bar
  902. b = Bitmap.new(1, 12)
  903. (1..6).each {|i| b.fill_rect(0, i-1, 1, 14-i*2, Color.new(40*i/3, 40*i/3, 40*i/3))}
  904. return b
  905. end
  906. #--------------------------------------------------------------------------
  907. # _empty_hud_green_bar
  908. # Creates the bitmap used for the empty HUD bars.
  909. #--------------------------------------------------------------------------
  910. def _empty_hud_green_bar
  911. b = Bitmap.new(1, 12)
  912. (1..6).each {|i| b.fill_rect(0, i-1, 1, 14-i*2, Color.new(0, 40*i/3, 0))}
  913. return b
  914. end
  915. #--------------------------------------------------------------------------
  916. # _hud_white_bar
  917. # Creates the bitmap used for the HUD bars.
  918. #--------------------------------------------------------------------------
  919. def _hud_white_bar
  920. b = Bitmap.new(1, 12)
  921. (1..6).each {|i| b.fill_rect(0, i-1, 1, 14-i*2, Color.new(40*i, 40*i, 40*i))}
  922. return b
  923. end
  924. #--------------------------------------------------------------------------
  925. # _hud_green_bar
  926. # Creates the bitmap used for the HUD bars.
  927. #--------------------------------------------------------------------------
  928. def _hud_green_bar
  929. b = Bitmap.new(1, 12)
  930. (1..6).each {|i| b.fill_rect(0, i-1, 1, 14-i*2, Color.new(0, 40*i, 0))}
  931. return b
  932. end
  933. #--------------------------------------------------------------------------
  934. # _empty_enemy_bar
  935. # Creates the bitmap used for the empty enemy bars.
  936. #--------------------------------------------------------------------------
  937. def _empty_enemy_bar
  938. b = Bitmap.new(1, 6)
  939. (1..3).each {|i| b.fill_rect(0, i-1, 1, 8-i*2, Color.new(0, 80*i/3, 0))}
  940. return b
  941. end
  942. #--------------------------------------------------------------------------
  943. # _enemy_bar
  944. # Creates the bitmap used for the enemy bars.
  945. #--------------------------------------------------------------------------
  946. def _enemy_bar
  947. b = Bitmap.new(1, 6)
  948. (1..3).each {|i| b.fill_rect(0, i-1, 1, 8-i*2, Color.new(0, 80*i, 0))}
  949. return b
  950. end
  951. #--------------------------------------------------------------------------
  952. # _beam1
  953. # Creates the bitmap used for the beam animation.
  954. #--------------------------------------------------------------------------
  955. def _beam1
  956. b = Bitmap.new(24, 1)
  957. (1...12).each {|i|
  958. b.fill_rect(i, 0, 1, 1, Color.new(255, 255, 255, i**2*3))
  959. b.fill_rect(23-i, 0, 1, 1, Color.new(255, 255, 255, i**2*3))}
  960. return b
  961. end
  962. #--------------------------------------------------------------------------
  963. # _grid
  964. # Creates the bitmap used for the AI behavior grid.
  965. #--------------------------------------------------------------------------
  966. def _grid
  967. b = Bitmap.new(360, 360)
  968. c1, c2 = Color.new(255, 255, 255), Color.new(0, 0, 0)
  969. b.fill_rect(0, 0, 48, 48, c1)
  970. b.fill_rect(24, 0, 24, 24, c2)
  971. b.fill_rect(0, 24, 24, 24, c2)
  972. c1.alpha = c2.alpha = 128
  973. b.fill_rect(1, 25, 22, 22, c1)
  974. b.fill_rect(25, 1, 22, 22, c1)
  975. b.fill_rect(1, 1, 22, 22, c2)
  976. b.fill_rect(25, 25, 22, 22, c2)
  977. b.blt(48, 0, b, Rect.new(0, 0, 48, 48))
  978. b.blt(0, 48, b, Rect.new(0, 0, 96, 48))
  979. b.blt(96, 0, b, Rect.new(0, 0, 96, 96))
  980. b.blt(0, 96, b, Rect.new(0, 0, 192, 96))
  981. b.blt(192, 0, b, Rect.new(0, 0, 192, 192))
  982. b.blt(0, 192, b, Rect.new(0, 0, 384, 192))
  983. return b
  984. end
  985. end
  986.  
  987. end
  988.  
  989. module BlizzABS
  990.  
  991. #============================================================================
  992. # BlizzABS::Combo
  993. #----------------------------------------------------------------------------
  994. # This class represents a Blizz-ABS combo and provides methods for handling.
  995. #============================================================================
  996.  
  997. class Combo
  998.  
  999. attr_accessor :id # combo ID
  1000. attr_accessor :aid # current action ID
  1001. attr_accessor :ch # character using the combo
  1002.  
  1003. attr_accessor :time # current time of the current action
  1004.  
  1005. attr_accessor :player # is the player performing this combo
  1006. attr_accessor :actor # is an actor performing this combo
  1007. attr_accessor :enemy # is an enemy performing this combo
  1008.  
  1009. attr_accessor :commands # stores commands for this combo
  1010. attr_accessor :moves # stores move commands for this combo
  1011. attr_accessor :inputs # stores input windows for this combo
  1012. attr_accessor :variables # stores variables for this combo
  1013.  
  1014. attr_accessor :total_actions # total number of actions
  1015. attr_accessor :animation # animation id of the current action
  1016. attr_accessor :sprite # sprite extension for overlay of the current action
  1017. attr_accessor :extension # is the sprite name an extension of the character
  1018. attr_accessor :animation_frames # sprite animation frames
  1019.  
  1020. attr_accessor :freeze_character # flag to freeze external input on character
  1021. attr_accessor :ended # has the combo ended
  1022.  
  1023. #--------------------------------------------------------------------------
  1024. # Initialization
  1025. #--------------------------------------------------------------------------
  1026. def initialize(id, ch)
  1027. # id of the combo
  1028. @id = id
  1029. # id of the current action
  1030. @aid = 0
  1031. # character performing combo
  1032. @ch = nil
  1033. # initialize variables
  1034. @variables = []
  1035. # 10 variables
  1036. 10.times {@variables.push(0)}
  1037. # initialize inputs
  1038. @inputs = []
  1039. # 10 inputs
  1040. 10.times {@inputs.push([[0], 0, 0, true])}
  1041. # set total number of actions
  1042. @total_actions = Combos.total_actions(self)
  1043. # set flag if combo performed by player
  1044. @player = true#@ch.is_a?(Game_Player)
  1045. # set flag if combo performed by actor
  1046. @actor = @ch.is_a?(Game_Actor)
  1047. # set flag if combo performed by enemy
  1048. @enemy = @ch.is_a?(Game_Enemy)
  1049. # begin combo
  1050. begin_combo(ch)
  1051. end
  1052. #--------------------------------------------------------------------------
  1053. # update
  1054. # Updates the combo while it is active
  1055. #--------------------------------------------------------------------------
  1056. def update
  1057. # increase frame counter
  1058. @time += 1
  1059. # update movement
  1060. update_move
  1061. # update input
  1062. update_input
  1063. # update commands
  1064. update_command
  1065. # update character
  1066. update_character
  1067. # end combo if reached end of commands
  1068. @ended = true if @commands.size == 0
  1069. end
  1070. #--------------------------------------------------------------------------
  1071. # update_move
  1072. # Updates the active movement route
  1073. #--------------------------------------------------------------------------
  1074. def update_move
  1075. if !@ch.moving? && @moves.size > 0
  1076. @moves.shift if proccess_move(@moves[0])
  1077. end
  1078. end
  1079. #--------------------------------------------------------------------------
  1080. # update_command
  1081. # Updates the active command list
  1082. #--------------------------------------------------------------------------
  1083. def update_command
  1084. while @commands.size > 0 && proccess_command(@commands[0])
  1085. @commands.shift
  1086. end
  1087. end
  1088. #--------------------------------------------------------------------------
  1089. # update_input
  1090. # Updates the active input windows
  1091. #--------------------------------------------------------------------------
  1092. def update_input
  1093. @inputs.each {|i|
  1094. # else if not succeeded
  1095. if !i[3]
  1096. # decrease counter
  1097. i[2] -= 1 if i[2] > 0
  1098. # initialize success
  1099. i[3] = true
  1100. i[0].each {|k|
  1101. # check for success based on trigger type
  1102. case i[1]
  1103. when INPress then i[3] = i[3] && Input.press?(k)
  1104. when INTrigger then i[3] = i[3] && Input.trigger?(k)
  1105. when INRelease then i[3] = i[3] && Input.release?(k)
  1106. end}
  1107. end}
  1108. end
  1109. #--------------------------------------------------------------------------
  1110. # update_character
  1111. # Updates the character
  1112. #--------------------------------------------------------------------------
  1113. def update_character
  1114. # freeze character input if flag is set
  1115. @ch.set_action(1) if @freeze_character
  1116. end
  1117. #--------------------------------------------------------------------------
  1118. # begin_combo
  1119. # Begins the combo
  1120. #--------------------------------------------------------------------------
  1121. def begin_combo(ch)
  1122. # set character
  1123. @ch = ch
  1124. # setup first action
  1125. setup_action(1)
  1126. end
  1127. #--------------------------------------------------------------------------
  1128. # setup_action
  1129. # Loads data and prepares the character to perform the current action in
  1130. # the combo
  1131. #--------------------------------------------------------------------------
  1132. def setup_action(id)
  1133. # set action id
  1134. @aid = id
  1135. # set time to zero
  1136. @time = 0
  1137. # get commands
  1138. @commands = Combos.commands(self)
  1139. # reset movement commands and input windows
  1140. @moves = []
  1141. # set animation data
  1142. @animation, @animation_frames, @sprite, @extension = Combos.anim_data(self)
  1143. # request combo sprite from player if needed
  1144. @ch.new_combo_sprite = true if @animation != 0 || @sprite != ''
  1145. end
  1146. #--------------------------------------------------------------------------
  1147. # proccess_command
  1148. # Processess a command
  1149. # Returns true if command processed, false if not
  1150. #--------------------------------------------------------------------------
  1151. def proccess_command(command)
  1152. # branch based on command type
  1153. case command[0]
  1154. when COMScript # script [code]
  1155. # evaluate script
  1156. result = eval(command[1])
  1157. when COMWait # wait [int]
  1158. # decrease wait counter by 1
  1159. command[1] -= 1
  1160. # proceed if wait time is up
  1161. return command[1] <= 0
  1162. when COMMove # move [int, int]
  1163. # add to move commands
  1164. @moves.push(command)
  1165. when COMTurn # turn [int]
  1166. # add to move commands
  1167. @moves.push(command)
  1168. when COMJump # jump [int, int]
  1169. # add to move commands
  1170. @moves.push(command)
  1171. when COMAttack # attack
  1172. # use attack
  1173. @ch.use_attack
  1174. when COMSkill # skill [int]
  1175. # use skill
  1176. @ch.use_skill($data_skills[command[1]])
  1177. when COMItem # item [int]
  1178. # use item
  1179. @ch.use_item($data_items[command[1]])
  1180. when COMDefend # defend [int]
  1181. # decrease time
  1182. time = command[1] - 1
  1183. # use defend
  1184. @ch.use_defend
  1185. # set penalty
  1186. @ch.set_action(1)
  1187. # if not done with command
  1188. if time > 0
  1189. # update the command counter
  1190. command[1] = time
  1191. # do not proceed
  1192. return false
  1193. end
  1194. when COMCharacter # character [CH, value]
  1195. # handle based on sub-command
  1196. case command[1]
  1197. when CHSpeed # move speed
  1198. # set movement speed
  1199. @ch.move_speed = command[2]
  1200. when CHFrequency # move frequency
  1201. # set movement frequency
  1202. @ch.move_frequency = command[2]
  1203. when CHSprite # change sprite
  1204. # set sprite
  1205. @ch.character_name = @ch.character_name_org = command[2]
  1206. when CHAnimation # play animation
  1207. # set animation
  1208. @ch.animation_id = command[2]
  1209. when CHFix # direction fix
  1210. # set direction fix flag
  1211. @ch.direction_fix = command[2]
  1212. when CHThrough # through
  1213. # set through flag
  1214. @ch.through = command[2]
  1215. when CHOnTop # always on top
  1216. # set always on top flag
  1217. @ch.always_on_top = command[2]
  1218. when CHOpacity # opacity
  1219. # set opacity
  1220. @ch.opacity = command[2]
  1221. end
  1222. when COMInput # create input window [int, [keys], IN, int]
  1223. # create new input window
  1224. @inputs[command[1]] = [command[2], command[3], command[4], false]
  1225. when COMVariable # variable [VAR, value1, '=', VAR, value2]
  1226. val1 = get_variable(command[1], command[2])
  1227. val2 = get_variable(command[4], command[5])
  1228. # branch handling based on operator type
  1229. case command[3]
  1230. when '+=' then val2 = val1 + val2 # add
  1231. when '-=' then val2 = val1 - val2 # subtract
  1232. when '*=' then val2 = val1 * val2 # multiply
  1233. when '/=' then val2 = val1 / val2 # divide
  1234. when '%=' then val2 = val1 % val2 # modulo
  1235. end
  1236. # set the variable
  1237. set_variable(command[1], command[2], val2)
  1238. when COMCondition # condition [VAR, value1, '==', VAR, value2]
  1239. # initialize result
  1240. result = false
  1241. # initialize values
  1242. val1 = get_variable(command[1], command[2])
  1243. val2 = get_variable(command[4], command[5])
  1244. # branch handling based on operator type
  1245. case command[3]
  1246. when '==' # equal to
  1247. # result is value 1 equal to value 2
  1248. result = val1 == val2
  1249. when '!=' # not equal to
  1250. # result is value 1 not equal to value 2
  1251. result = val1 != val2
  1252. when '>' # greater than
  1253. # result is value 1 equal to value 2
  1254. result = val1 > val2
  1255. when '>=' # greater than or equal to
  1256. # result is value 1 not equal to value 2
  1257. result = val1 >= val2
  1258. when '<=' # less than
  1259. # result is value 1 equal to value 2
  1260. result = val1 < val2
  1261. when '<=' # less than or equal to
  1262. # result is value 1 not equal to value 2
  1263. result = val1 <= val2
  1264. end
  1265. # if input or script
  1266. if command[1] == VARInput || command[1] == VARScript
  1267. # value 1 contains the result
  1268. result = val1
  1269. # do not proceed if waiting on an input window
  1270. if command[1] == VARInput && @inputs[command[2]][2] > 0 && !result
  1271. return false
  1272. end
  1273. end
  1274. # skip next command if exists and condition not met
  1275. @commands.delete_at(1) if !result && @commands.size > 1
  1276. when COMFreeze # freeze input [bool]
  1277. # set freeze input flag
  1278. @freeze_character = command[1]
  1279. when COMCompletion # wait for move completion
  1280. # proceed if no more moves and character no longer moving
  1281. return @moves.size == 0 && !@ch.moving?
  1282. when COMGoTo # go to action [int]
  1283. raise 'ERROR: Invalid action' if !is_valid_action?(command[1])
  1284. # setup the action
  1285. setup_action(command[1])
  1286. # do not proceed - new set of commands
  1287. return false
  1288. when COMAbort # abort
  1289. # set ended flag
  1290. @ended = true
  1291. end
  1292. return true
  1293. end
  1294. #--------------------------------------------------------------------------
  1295. # proccess_move
  1296. # Processess a move command
  1297. # Returns true if command fully processed, false if not
  1298. #--------------------------------------------------------------------------
  1299. def proccess_move(command)
  1300. # branch based on command type
  1301. case command[0]
  1302. # move
  1303. when COMMove
  1304. # get direction
  1305. dir = get_direction(command[1])
  1306. # get number of steps remaining
  1307. steps = command[2] - 1
  1308. # make character move depending on direction
  1309. case dir
  1310. when 1 then @ch.move_lower_left
  1311. when 2 then @ch.move_down(dir)
  1312. when 3 then @ch.move_lower_right
  1313. when 4 then @ch.move_left(dir)
  1314. when 6 then @ch.move_right(dir)
  1315. when 7 then @ch.move_upper_left
  1316. when 8 then @ch.move_up(dir)
  1317. when 9 then @ch.move_upper_right
  1318. end
  1319. # proceed if no more steps
  1320. return true if steps == 0
  1321. # update steps counter
  1322. command[2] = steps
  1323. # do not proceed as there are more steps to be executed
  1324. return false
  1325. # turn
  1326. when COMTurn
  1327. # make character turn to face direction
  1328. @ch.direction = get_direction(command[1])
  1329. # jump
  1330. when COMJump
  1331. # get direction
  1332. dir = get_direction(command[1])
  1333. # get range
  1334. range = command[2]
  1335. # set jumping direction
  1336. x, y = BlizzABS::Cache::DirOffsets[dir]
  1337. # jump into direction with range
  1338. @ch.jump(x*range, y*range, dir)
  1339. end
  1340. # proceed
  1341. return true
  1342. end
  1343. #--------------------------------------------------------------------------
  1344. # get_variable
  1345. # type - variable type
  1346. # value - value type
  1347. # Returns the variable from the given command data
  1348. #--------------------------------------------------------------------------
  1349. def get_variable(type, value)
  1350. # initialize
  1351. var = 0
  1352. # branch handling based on variable type
  1353. case type
  1354. when VARGame # game variable
  1355. # variable is the game variable
  1356. var = $game_variables[value]
  1357. when VARCombo # combo variable
  1358. # variable is the combo variable
  1359. var = @variables[value]
  1360. when VARCharacter # character variable
  1361. # branch handling based on value type
  1362. case value
  1363. when VALHp # battler hp
  1364. # variable is the battler's hp
  1365. var = @ch.battler.hp
  1366. when VALSp # battler sp
  1367. # variable is the battler's hp
  1368. var = @ch.battler.sp
  1369. when VALMaxHp # battler max hp
  1370. # variable is the battler's max hp
  1371. var = @ch.battler.maxhp
  1372. when VALMaxSp # battler max sp
  1373. # variable is the battler's max sp
  1374. var = @ch.battler.maxsp
  1375. when VALState # battler states
  1376. # variable is the amount of states on battler
  1377. var = @ch.battler.states.size
  1378. when VALExp # battler exp
  1379. # variable is the battler's exp
  1380. var = @ch.battler.exp
  1381. when VALLevel # battler level
  1382. # variable is the battler's level
  1383. var = @ch.battler.level
  1384. when VALTile # tile id
  1385. # variable is the character's current tile
  1386. var = @ch.tile_id
  1387. when VALDirection # battler direction
  1388. # variable is the character's current direction
  1389. var = @ch.direction
  1390. end
  1391. when VARInput # input
  1392. # variable is input success
  1393. var = @inputs[value][3]
  1394. when VARConstant # constant
  1395. # variable is just the value given
  1396. var = value
  1397. when VARScript # script
  1398. # variable is just the script given
  1399. var = eval(value)
  1400. end
  1401. return var
  1402. end
  1403. #--------------------------------------------------------------------------
  1404. # set_variable
  1405. # type - variable type
  1406. # value - value type
  1407. # setvalue - value to set to
  1408. # sets the variable from the given command data
  1409. #--------------------------------------------------------------------------
  1410. def set_variable(type, value, setvalue)
  1411. # branch handling based on variable type
  1412. case type
  1413. when VARGame # game variable
  1414. # set game variable to value
  1415. $game_variables[value] = setvalue
  1416. when VARCombo # combo variable
  1417. # set combo variable to value
  1418. @variables[value] = setvalue
  1419. when VARCharacter # character variable
  1420. # branch handling based on value type
  1421. case value
  1422. when VALHp # battler hp
  1423. # set battler's hp to value
  1424. @ch.battler.hp = setvalue
  1425. when VALSp # battler sp
  1426. # set battler's hp to value
  1427. @ch.battler.sp = setvalue
  1428. when VALMaxHp # battler max hp
  1429. # set battler's max hp to value
  1430. @ch.battler.maxhp = setvalue
  1431. when VALMaxSp # battler max sp
  1432. # set battler's max sp to value
  1433. @ch.battler.maxsp = setvalue
  1434. when VALExp # battler exp
  1435. # set battler's exp to value
  1436. @ch.battler.exp = setvalue
  1437. when VALLevel # battler level
  1438. # set battler's level to value
  1439. @ch.battler.level = setvalue
  1440. when VALDirection # battler direction to value
  1441. # set character's current direction
  1442. @ch.direction = setvalue
  1443. end
  1444. end
  1445. end
  1446. #--------------------------------------------------------------------------
  1447. # get_direction
  1448. # data - command data
  1449. # Returns the 0-10 direction from the given command data
  1450. #--------------------------------------------------------------------------
  1451. def get_direction(data)
  1452. # default direction
  1453. dir = 0
  1454. # handle special directions
  1455. case data
  1456. when DIR90Right
  1457. # go back two indices in circle
  1458. dir = Cache::LoopDir8[(Cache::LoopDir8.index(@ch.direction) + 6) % 8]
  1459. # when 90 degrees left
  1460. when DIR90Left
  1461. # go forward two indices in circle
  1462. dir = Cache::LoopDir8[(Cache::LoopDir8.index(@ch.direction) + 2) % 8]
  1463. # when forward
  1464. when DIRForward
  1465. # character's direction
  1466. dir = @ch.direction
  1467. # when backward
  1468. when DIRBackward
  1469. # character's direction
  1470. dir = 10 - @ch.direction
  1471. # when toward player
  1472. when DIRTowardPlayer
  1473. # get distance to player
  1474. dx = $game_player.x - @ch.x
  1475. dy = $game_player.y - @ch.y
  1476. # direction toward player
  1477. dir = $BlizzABS.util.get_direction(dx, dy)
  1478. # when away from player
  1479. when DIRAwayPlayer
  1480. # get from to player
  1481. dx = @ch.x - $game_player.x
  1482. dy = @ch.y - $game_player.y
  1483. # direction away from player
  1484. dir = $BlizzABS.util.get_direction(dx, dy)
  1485. # Random 4 way direction
  1486. when DIRRandom4
  1487. # Random 4 way direction
  1488. dir = Cache::Dir4[rand(4)]
  1489. # Random 8 way direction
  1490. when DIRRandom8
  1491. # Random 8 way direction
  1492. dir = Cache::Dir8[rand(8)]
  1493. # when 45 degrees right
  1494. when DIR45Right
  1495. # go to previous index in circle
  1496. dir = Cache::LoopDir8[(Cache::LoopDir8.index(@ch.direction) + 7) % 8]
  1497. # when 45degrees left
  1498. when DIR45Left
  1499. # go to next index in circle
  1500. dir = Cache::LoopDir8[(Cache::LoopDir8.index(@ch.direction) + 1) % 8]
  1501. # no special direction
  1502. else
  1503. # set to 0-10 direction
  1504. dir = data
  1505. end
  1506. return dir
  1507. end
  1508. #--------------------------------------------------------------------------
  1509. # is_valid_action?
  1510. # aid - id of action
  1511. # Tests if aid is a valid action for this combo.
  1512. #--------------------------------------------------------------------------
  1513. def is_valid_action?(aid)
  1514. return aid > 0 && aid <= @total_actions
  1515. end
  1516.  
  1517. end
  1518.  
  1519. end
  1520.  
  1521. module BlizzABS
  1522.  
  1523. #============================================================================
  1524. # BlizzABS::Processor
  1525. #----------------------------------------------------------------------------
  1526. # This class provides methods for Blizz-ABS handling.
  1527. #============================================================================
  1528.  
  1529. class Processor
  1530.  
  1531. # setting all accessible variables
  1532. attr_accessor :actors
  1533. attr_accessor :pets
  1534. attr_accessor :monsters
  1535. attr_accessor :AI
  1536. attr_reader :player
  1537. attr_reader :cache
  1538. attr_reader :util
  1539. attr_reader :controls
  1540. #--------------------------------------------------------------------------
  1541. # Initialization
  1542. #--------------------------------------------------------------------------
  1543. def initialize
  1544. # load player controller
  1545. @player = Controller.new
  1546. # create Blizz-ABS Cache
  1547. @cache = Cache.new
  1548. # utilities
  1549. @util = Utility.new
  1550. # refresh passability data
  1551. @util.check_map_data if $DEBUG
  1552. # create handler for player battle input
  1553. @controls = Controls.new
  1554. # AI instance
  1555. @AI = AI.new
  1556. # map actors, summoned pets and summoned monsters
  1557. @actors, @pets, @monsters = [], [], []
  1558. # counters for pets and monsters
  1559. @summon_time = {}
  1560. end
  1561. #--------------------------------------------------------------------------
  1562. # battlers
  1563. # Returns actors and all summons from the party.
  1564. #--------------------------------------------------------------------------
  1565. def battlers
  1566. return (@actors + @pets + @monsters)
  1567. end
  1568. #--------------------------------------------------------------------------
  1569. # summons
  1570. # Returns only summons from the party.
  1571. #--------------------------------------------------------------------------
  1572. def summons
  1573. return (@pets + @monsters)
  1574. end
  1575. #--------------------------------------------------------------------------
  1576. # update
  1577. # Updates Blizz-ABS processes.
  1578. #--------------------------------------------------------------------------
  1579. def update
  1580. # update each projectile and trap
  1581. $BlizzABS.cache.remotes.each {|remote| remote.update}
  1582. # update player battle input
  1583. @controls.update
  1584. # update summons
  1585. update_summons
  1586. # stop if scene is not Scene_Map
  1587. return if !$scene.is_a?(Scene_Map)
  1588. # update killed events
  1589. update_killed
  1590. # remove expired events from the map
  1591. event_removal
  1592. # remove expired summons from the map
  1593. summon_removal
  1594. # check special status effects
  1595. check_special_states
  1596. end
  1597. #--------------------------------------------------------------------------
  1598. # update_summons
  1599. # Updates all summons.
  1600. #--------------------------------------------------------------------------
  1601. def update_summons
  1602. # for each summoned battler
  1603. @summon_time.each_key {|summon|
  1604. # decrease counter
  1605. @summon_time[summon] -= 1
  1606. # if counter expired
  1607. remove_summon(summon) if @summon_time[summon] <= 0}
  1608. end
  1609. #--------------------------------------------------------------------------
  1610. # summon_pet
  1611. # pet - the pet to summon
  1612. # time - the time to remain
  1613. # Executes the summoning of a pet.
  1614. #--------------------------------------------------------------------------
  1615. def summon_pet(pet, time)
  1616. # add pet
  1617. @pets.push(pet)
  1618. # set timer
  1619. @summon_time[pet] = time * 40
  1620. # stop if scene not Scene_Map or spriteset doesn't exist
  1621. return if !$scene.is_a?(Scene_Map) || $scene.spriteset == nil
  1622. # create sprite
  1623. sprite = Sprite_Character.new($scene.spriteset.viewport1, pet)
  1624. # add to spriteset handler
  1625. $scene.spriteset.character_sprites.push(sprite)
  1626. end
  1627. #--------------------------------------------------------------------------
  1628. # summon_monster
  1629. # monster - the monster to summon
  1630. # time - the time to remain
  1631. # Executes the summoning of a monster.
  1632. #--------------------------------------------------------------------------
  1633. def summon_monster(monster, time)
  1634. # add monster
  1635. @monsters.push(monster)
  1636. # set timer
  1637. @summon_time[monster] = time * 40
  1638. # stop if scene not Scene_Map or spriteset doesn't exist
  1639. return if !$scene.is_a?(Scene_Map) || $scene.spriteset == nil
  1640. # create sprite
  1641. sprite = Sprite_Character.new($scene.spriteset.viewport1, monster)
  1642. # add to spriteset handler
  1643. $scene.spriteset.character_sprites.push(sprite)
  1644. end
  1645. #--------------------------------------------------------------------------
  1646. # remove_summon
  1647. # summon - the summoned pet or monster to remove
  1648. # Removes the summon from the game.
  1649. #--------------------------------------------------------------------------
  1650. def remove_summon(summon)
  1651. # remove this counter
  1652. @summon_time.delete(summon)
  1653. # make it "die"
  1654. summon.battler.hp = 0
  1655. # delete from events in case an enemy summoned this summon
  1656. $game_map.events.delete(summon)
  1657. end
  1658. #--------------------------------------------------------------------------
  1659. # summoned?
  1660. # character - the character to check
  1661. # Checks if the character was summoned.
  1662. #--------------------------------------------------------------------------
  1663. def summoned?(character)
  1664. return (@pets + @monsters).include?(character)
  1665. end
  1666. #--------------------------------------------------------------------------
  1667. # summoned_actor?
  1668. # id - the actor ID
  1669. # Checks if the actor was summoned.
  1670. #--------------------------------------------------------------------------
  1671. def summoned_actor?(id)
  1672. return (@pets + @monsters).any? {|character| character.battler.id == id}
  1673. end
  1674. #--------------------------------------------------------------------------
  1675. # update_killed
  1676. # Updates data regarding killed battlers.
  1677. #--------------------------------------------------------------------------
  1678. def update_killed
  1679. # deleted killed
  1680. deleted_killed = []
  1681. # iterate through all killed
  1682. $game_system.killed.each_key {|key|
  1683. # decrease respawn counter
  1684. $game_system.killed[key] -= 1
  1685. # if dead enemy has event code to be executed
  1686. if key.execute
  1687. # update interpreter
  1688. key.update
  1689. # if respawn counter reached 0
  1690. elsif $game_system.killed[key] <= 0
  1691. # remove from map
  1692. $game_map.events.delete(key.id)
  1693. # if respawning available
  1694. if $game_system.respawn_time > 0 || key.respawn_point != nil
  1695. # add new enemy on old enemy's place
  1696. $game_map.events[key.id] = respawn_enemy(key)
  1697. end
  1698. # this enemy is not "killed" anymore
  1699. deleted_killed.push(key)
  1700. end}
  1701. # remove deleted values
  1702. deleted_killed.each {|key| $game_system.killed.delete(key)}
  1703. end
  1704. #--------------------------------------------------------------------------
  1705. # event_removal
  1706. # Removes expired events from the map including battlers and dropped
  1707. # items.
  1708. #--------------------------------------------------------------------------
  1709. def event_removal
  1710. # iterate through all events on the map
  1711. $game_map.events.values.each {|event|
  1712. # if event is Map_Enemy
  1713. if event.is_a?(Map_Enemy)
  1714. # if event is actually on the map
  1715. if event.precondition
  1716. # start removing the enemy if he's dead
  1717. remove_enemy(event) if !event.valid? || event.battler.dead?
  1718. # if enemy spriteset missing
  1719. if event.character_name == '' && event.tile_id < 384
  1720. # remove completely
  1721. $game_map.events.delete(event.id)
  1722. end
  1723. end
  1724. # if event is dropped item and either item taken or stay time expired
  1725. elsif event.dropped? && event.terminate
  1726. # remove completely
  1727. $game_map.events.delete(event.id)
  1728. end}
  1729. end
  1730. #--------------------------------------------------------------------------
  1731. # summon_removal
  1732. # Removes expired summons from the map.
  1733. #--------------------------------------------------------------------------
  1734. def summon_removal
  1735. # remove all expired pets
  1736. @pets.clone.each {|p| @pets.delete(p) if p.terminate}
  1737. # remove all expired monsters
  1738. @monsters.clone.each {|m| @monsters.delete(m) if m.terminate}
  1739. end
  1740. #--------------------------------------------------------------------------
  1741. # battlers_refresh
  1742. # Replaces correctly named events with Blizz-ABS battlers and other
  1743. # Blizz-ABS specific events.
  1744. #--------------------------------------------------------------------------
  1745. def battlers_refresh
  1746. # killed battlers array
  1747. $game_system.reset_abs_data
  1748. # for all events
  1749. $game_map.events.each_key {|i|
  1750. # execute substitution based on names if the event exists
  1751. check_event_name(i) if $game_map.events[i] != nil}
  1752. # now that enemies are created, check connections
  1753. $game_map.events.each_key {|i|
  1754. check_enemy_multi_body(i) if $game_map.events[i].is_a?(Map_Battler)}
  1755. end
  1756. #--------------------------------------------------------------------------
  1757. # check_event_name
  1758. # event_id - event ID
  1759. # Checks and replaces the event.
  1760. #--------------------------------------------------------------------------
  1761. def check_event_name(event_id)
  1762. # temporary variable
  1763. event = $game_map.map.events[event_id]
  1764. # initialize
  1765. enemy, time, attr, id, group, lock, drop = 0, 5, 0x00, nil, nil, nil, nil
  1766. hwidth, hheight = 32, 32
  1767. move = immortal = object = full_passable = no_jump = center_sprite = false
  1768. no_dmg = false
  1769. # if lock setting exists
  1770. if event.name.clone.gsub!(/\\lock\[(\d+)\]/) {"#[$1]"}
  1771. # get lock setting
  1772. lock = $1.to_i if event.name.clone.gsub!(/\\lock\[(\d+)\]/) {"#[$1]"}
  1773. end
  1774. # set allow jump flag if allow jump disabled
  1775. no_jump = true if event.name.clone.gsub!('\\nojump') {''}
  1776. # set center sprite flag if allow jump disabled
  1777. center_sprite = true if event.name.clone.gsub!('\\cspr') {''}
  1778. # set center sprite flag if allow jump disabled
  1779. no_dmg = true if event.name.clone.gsub!('\\nodmg') {''}
  1780. # if hitbox command exists
  1781. if event.name.clone.gsub!(/\\hsize\[(\d+),(\d+)\]/) {"#[$1,$2]"}
  1782. # set hitbox size
  1783. hwidth = $1.to_i
  1784. hheight = $2.to_i
  1785. end
  1786. # set internal variable to ID (enemy)
  1787. if event.name.clone.gsub!(/\\[Ee]\[(\d+)\]/) {"#[$1]"}
  1788. # temporary variable for ID
  1789. id = $1.to_i
  1790. # set internal variable to ID (enemy)
  1791. if event.name.clone.gsub!(/\\[Gg]\[(\d+)\]/) {"#[$1]"}
  1792. # temporary variable for group
  1793. group = $1.to_i
  1794. else
  1795. # default enemy group
  1796. group = BlizzABS::Alignments::ENEMY_GROUP
  1797. end
  1798. # set internal variable to array of IDs (Respawn Point)
  1799. elsif event.name.clone.gsub!(/\\respawn\[([\d, ]+)\]/) {"#[$1]"}
  1800. # temporary variable for array of IDs
  1801. id = eval("[#{$1}]")
  1802. # if time setting exists
  1803. if event.name.clone.gsub!(/\\time\[(\d+)\]/) {"#[$1]"}
  1804. # get time setting
  1805. time = $1.to_i
  1806. end
  1807. # dropped item
  1808. elsif event.name.clone.gsub!(/\\drop\[(\d+)\]/) {"#[$1]"}
  1809. # temporary variable for time
  1810. drop = $1.to_i
  1811. end
  1812. # if id is valid and enemy exists in database
  1813. if id.is_a?(Numeric) && $data_enemies[id] != nil
  1814. # set move flag if moving disabled
  1815. move = true if event.name.clone.gsub!('\\move') {''}
  1816. # set immortal flag if immortal enemy
  1817. immortal = true if event.name.clone.gsub!('\\immortal') {''}
  1818. # set full passability if passable enemy
  1819. full_passable = true if event.name.clone.gsub!('\\pass') {''}
  1820. # get AI setup
  1821. attr, delay, view, hear = setup_enemy_ai(id)
  1822. # custom AI setup exists
  1823. custom = (event.name.clone.gsub!(/\\ai\[(\d+)\]/) {"#[$1]"} != nil)
  1824. # add AI attribute setup if custom
  1825. attr = eval("0b#{$1}") if custom
  1826. # replace the real event with the new enemy
  1827. $game_map.events[event_id] = Map_Enemy.new($game_map.map_id, event,
  1828. id, group, attr, move, immortal, full_passable, custom,
  1829. delay, view, hear, no_jump)
  1830. # increase original enemy count
  1831. $game_system.add_battler_number(group, 1)
  1832. # if hide command exists
  1833. if event.name.clone.gsub!('\\hide') {''}
  1834. # set flag to hide energy bar
  1835. $game_map.events[event_id].hide_health = true
  1836. end
  1837. # if Respawn Point
  1838. elsif id.is_a?(Array)
  1839. # make this event a Respawn Point
  1840. $game_map.events[event_id].respawn_ids = id
  1841. # set respawn time
  1842. $game_map.events[event_id].respawn_time = time
  1843. # for convenience and easier reference
  1844. $game_map.respawns.push($game_map.events[event_id])
  1845. # if dropped item
  1846. elsif drop != nil
  1847. # modify event to semi-drop event
  1848. $game_map.events[event_id].activate_drop_mode(drop * 40)
  1849. else
  1850. # if special event renamed back to normal event
  1851. if !$game_map.events[event_id].is_a?(Game_Event)
  1852. # create normal event again
  1853. $game_map.events[event_id] = Game_Event.new($game_map.map_id, event)
  1854. end
  1855. # if lock setting doesn't exist
  1856. if lock == nil
  1857. # set execution lock time to default
  1858. $game_map.events[event_id].lock_time = BlizzABS::Config::EVENT_LOCK
  1859. else
  1860. # set execution lock time
  1861. $game_map.events[event_id].lock_time = lock
  1862. end
  1863. end
  1864. $game_map.events[event_id].no_dmg_sprites = no_dmg
  1865. $game_map.events[event_id].no_jump = no_jump
  1866. $game_map.events[event_id].center_sprite = center_sprite
  1867. $game_map.events[event_id].hitbox_width = hwidth
  1868. $game_map.events[event_id].hitbox_height = hheight
  1869. end
  1870. #--------------------------------------------------------------------------
  1871. # check_enemy_multi_body
  1872. # event_id - event ID
  1873. # Checks the multi-body setup.
  1874. #--------------------------------------------------------------------------
  1875. def check_enemy_multi_body(event_id)
  1876. # get event
  1877. event = $game_map.events[event_id]
  1878. # if event is connected to a body
  1879. if event.name.clone.gsub!(/\\connect\[(\d+)\]/) {"#[$1]"}
  1880. # event id
  1881. id = $1.to_i
  1882. # body event
  1883. body = $game_map.events[id]
  1884. # if body event exists
  1885. if body != nil
  1886. # reset ai to body ai
  1887. attr, delay, view, hear =
  1888. setup_enemy_ai($game_map.events[id].battler_id)
  1889. # keep group, move flag, and immortal
  1890. group, custom, immortal = body.ai.group, body.ai.custom, body.immortal
  1891. # keep ai and no jump
  1892. move, nojump = event.move_flag, event.no_jump
  1893. # create new enemy like body
  1894. $game_map.events[event_id] = Map_Enemy.new(
  1895. $game_map.map_id, event, $game_map.events[id].battler_id, group,
  1896. attr, move, immortal, $game_map.events[id].full_passable, custom,
  1897. delay, view, hear, nojump)
  1898. #($game_map.map_id, event,
  1899. #id, group, attr, move, immortal, full_passable, custom,
  1900. #delay, view, hear, no_jump)
  1901. # set battler to body battler
  1902. $game_map.events[event_id].battler = $game_map.events[id].battler
  1903. # set body to body event
  1904. $game_map.events[event_id].body = body
  1905. end
  1906. end
  1907. end
  1908. #--------------------------------------------------------------------------
  1909. # setup_enemy_ai
  1910. # id - enemy ID
  1911. # Returns the AI setup.
  1912. #--------------------------------------------------------------------------
  1913. def setup_enemy_ai(id)
  1914. # get attributes
  1915. attr = BlizzABS::Enemies.ai(id)
  1916. # if unique AI setup exists
  1917. if attr != nil
  1918. # add AI attribute setup
  1919. attr = eval("0b#{attr}")
  1920. else
  1921. # default AI attribute setup
  1922. attr = eval("0b#{BlizzABS::Config::AI_DEFAULT_ATTRIBUTES}")
  1923. end
  1924. # get unique AI Delay Time
  1925. delay = BlizzABS::Enemies.delay(id)
  1926. # get default if not existent
  1927. delay = BlizzABS::Config::AI_DELAY_TIME if delay == nil
  1928. # get unique Perception
  1929. view = BlizzABS::Enemies.perception(id)
  1930. # if unique perception exists
  1931. if view != nil
  1932. # split up
  1933. view, hear = view
  1934. else
  1935. # get defaults
  1936. view = BlizzABS::Config::VIEW_RANGE
  1937. hear = BlizzABS::Config::HEARING_RANGE_RATIO
  1938. end
  1939. # result
  1940. return [attr, delay, view, hear]
  1941. end
  1942. #--------------------------------------------------------------------------
  1943. # remove_enemy
  1944. # enemy - the killed enemy event
  1945. # Processes the after-death period of enemies.
  1946. #--------------------------------------------------------------------------
  1947. def remove_enemy(enemy)
  1948. # stop except if enemy event code is to be executed or enemy is erased
  1949. return if enemy.execute || enemy.erased || enemy.body != nil
  1950. # start event code if there is some
  1951. enemy.start if enemy.trigger == BlizzABS::CETDeath
  1952. # remove except if code needs to be executed
  1953. $game_map.events.delete(enemy.id) unless enemy.execute
  1954. # get all dropped items on the map
  1955. items = drop_items(enemy)
  1956. # if not dropping
  1957. if !BlizzABS::Config::ITEM_DROP
  1958. # add items into inventory
  1959. items.each {|item|
  1960. case item
  1961. when RPG::Weapon then $game_party.gain_weapon(item.id, 1)
  1962. when RPG::Armor then $game_party.gain_armor(item.id, 1)
  1963. when RPG::Item then $game_party.gain_item(item.id, 1)
  1964. end}
  1965. # clear items
  1966. items = []
  1967. end
  1968. # experience result
  1969. exp_result(enemy)
  1970. # gold result
  1971. gold = gold_result(enemy)
  1972. # if not using drop gold mode
  1973. if BlizzABS::Config::GOLD_DROP == ''
  1974. # just increase gold
  1975. $game_party.gain_gold(gold)
  1976. # if dropping any gold
  1977. elsif gold > 0
  1978. # add gold to items
  1979. items = [gold] + items
  1980. end
  1981. # execute all additional enemy results
  1982. additional_result(enemy)
  1983. # if using corpses
  1984. if BlizzABS::Config::CORPSES
  1985. # if using empty corpses or any drop exists
  1986. if BlizzABS::Config::EMPTY_CORPSES || items.size > 0
  1987. # create a corpse dropped items
  1988. drop_event(items, enemy.real_x, enemy.real_y, enemy)
  1989. end
  1990. else
  1991. # create all necessary dropped items
  1992. items.each {|item| drop_event([item], enemy.real_x, enemy.real_y)}
  1993. end
  1994. end
  1995. #--------------------------------------------------------------------------
  1996. # drop_items
  1997. # enemy - the killed enemy event
  1998. # Returns array of items that will be dropped.
  1999. #--------------------------------------------------------------------------
  2000. def drop_items(enemy)
  2001. # initialize array
  2002. items = []
  2003. # if using Multi-Drop from Tons of Add-ons
  2004. if $tons_version != nil && $tons_version >= 5.98 &&
  2005. TONS_OF_ADDONS::MULTI_DROP
  2006. # gets all dropped items
  2007. items += BlizzCFG.dropped_items(enemy.battler)
  2008. # if got item
  2009. elsif rand(100) < enemy.battler.treasure_prob
  2010. # if enemy drops item
  2011. if enemy.battler.item_id > 0
  2012. # set ID
  2013. items.push($data_items[enemy.battler.item_id])
  2014. # if enemy drops weapon
  2015. elsif enemy.battler.weapon_id > 0
  2016. # set ID
  2017. items.push($data_weapons[enemy.battler.weapon_id])
  2018. # if enemy drops armor
  2019. elsif enemy.battler.armor_id > 0
  2020. # set ID
  2021. items.push($data_armors[enemy.battler.armor_id])
  2022. end
  2023. end
  2024. # result
  2025. return items
  2026. end
  2027. #--------------------------------------------------------------------------
  2028. # exp_result
  2029. # enemy - the killed enemy event
  2030. # Processes EXP gain after the death of an enemy.
  2031. #--------------------------------------------------------------------------
  2032. def exp_result(enemy)
  2033. # stop if enemy gives no EXP
  2034. return 0 if enemy.exp == 0
  2035. # get EXP
  2036. exp = enemy.exp
  2037. # if Tons is there
  2038. if $tons_version != nil
  2039. # if version is correct and using Different Difficulties
  2040. if $tons_version >= 6.4 && TONS_OF_ADDONS::DIFFICULTY
  2041. # multiply gained gold
  2042. exp = exp * $game_system.exp_rate / 100
  2043. end
  2044. # if version is correct and using Passive Skills
  2045. if $tons_version >= 6.5 && $game_system.PASSIVE_SKILLS
  2046. # multiply gained gold with each actor's rate
  2047. $game_party.actors.each {|actor| exp *= actor.exp_rate}
  2048. exp = exp.to_i
  2049. end
  2050. end
  2051. # bonus exp if bonus or unshared and last attacked battler exists
  2052. if Config::EXP_MODE > 0 && enemy.last_hit_by != nil
  2053. bat = enemy.last_hit_by
  2054. bat.exp += exp if !bat.cant_get_exp?
  2055. end
  2056. # shared exp if bonus or shared, but exp is split evenly among party
  2057. if Config::EXP_MODE < 2
  2058. ind_exp = exp / $game_party.actors.size
  2059. # iterate through all actors and pets
  2060. ($BlizzABS.actors + $BlizzABS.pets).each {|b|
  2061. # increase EXP if actor is valid and actor can get EXP
  2062. b.battler.exp += ind_exp if b.valid? && !b.battler.cant_get_exp?}
  2063. end
  2064. # return exp value for further processing
  2065. return exp
  2066. end
  2067. #--------------------------------------------------------------------------
  2068. # gold_result
  2069. # enemy - the killed enemy event
  2070. # Processes gold gain after the death of an enemy.
  2071. #--------------------------------------------------------------------------
  2072. def gold_result(enemy)
  2073. # stop if enemy drops no gold
  2074. return 0 if enemy.gold == 0
  2075. # get gold
  2076. gold = enemy.gold
  2077. # if Tons is there
  2078. if $tons_version != nil
  2079. # if version is correct and using Different Difficulties
  2080. if $tons_version >= 6.4 && TONS_OF_ADDONS::DIFFICULTY
  2081. # multiply gained gold
  2082. gold = gold * $game_system.gold_rate / 100
  2083. end
  2084. # if version is correct and using Passive Skills
  2085. if $tons_version >= 6.5 && $game_system.PASSIVE_SKILLS
  2086. # multiply gained gold with each actor's rate
  2087. $game_party.actors.each {|actor| gold *= actor.gold_rate}
  2088. gold = gold.to_i
  2089. end
  2090. end
  2091. # return gold value for further processing
  2092. return gold
  2093. end
  2094. #--------------------------------------------------------------------------
  2095. # additional_result
  2096. # enemy - the killed enemy event
  2097. # Processes additional gains after the death of an enemy.
  2098. #--------------------------------------------------------------------------
  2099. def additional_result(enemy)
  2100. # if Tons of Add-ons there and EQUAP active
  2101. if $tons_version != nil && $tons_version >= 7.32 &&
  2102. TONS_OF_ADDONS::EQUAP_SKILLS
  2103. # get AP result
  2104. ap = BlizzCFG.gainap(enemy.id)
  2105. # for each actor
  2106. $BlizzABS.battlers.each {|battler|
  2107. # if actor can gain AP
  2108. if battler.valid? && (!battler.battler.dead? || GAIN_DEAD)
  2109. # add AP
  2110. battler.battler.add_ap(ap)
  2111. end}
  2112. end
  2113. end
  2114. #--------------------------------------------------------------------------
  2115. # respawn_enemy
  2116. # enemy - the killed enemy event
  2117. # Processes the respawn of a dead enemy.
  2118. #--------------------------------------------------------------------------
  2119. def respawn_enemy(enemy)
  2120. # create new enemy on old enemy's template
  2121. new_enemy = Map_Enemy.new($game_map.map_id, enemy)
  2122. # gets the respawn coordinates
  2123. x, y = get_respawn_coordinates(enemy)
  2124. # no respawn position found
  2125. return nil if x == nil || y == nil
  2126. # move enemy to position
  2127. new_enemy.moveto(x, y)
  2128. # if scene is Scene_Map and spriteset exists
  2129. if $scene.is_a?(Scene_Map) && $scene.spriteset != nil
  2130. # create sprite for respawned enemy
  2131. sprite = Sprite_Character.new($scene.spriteset.viewport1, new_enemy)
  2132. # set respawning flag
  2133. sprite.respawning = true
  2134. # add new sprite into spriteset
  2135. $scene.spriteset.character_sprites.push(sprite)
  2136. end
  2137. # enemy is invisible at first
  2138. new_enemy.opacity = 0
  2139. # return new enemy
  2140. return new_enemy
  2141. end
  2142. #--------------------------------------------------------------------------
  2143. # get_respawn_coordinates
  2144. # enemy - the killed enemy event
  2145. # Gets the respawning coordinates for the new enemy.
  2146. #--------------------------------------------------------------------------
  2147. def get_respawn_coordinates(enemy)
  2148. # if fixed Respawn Point exists
  2149. if enemy.respawn_point != nil
  2150. # coordinates of the Respawn Point
  2151. return [enemy.respawn_point.x, enemy.respawn_point.y]
  2152. end
  2153. # get virtual map passability
  2154. v_map, passables = $game_map.virtual_passability, []
  2155. # get pixel movement rate
  2156. pix = $BlizzABS.pixel
  2157. # find all passable tiles
  2158. (0...v_map.xsize).each {|x| (0...v_map.ysize).each {|y|
  2159. # if passable and enemy may respawn and no event on position
  2160. if v_map[x, y] != 0x00 && !BlizzABS::Config::NO_ENEMY_TAGS.include?(
  2161. $game_map.terrain_tag(x, y)) && $game_map.event_passable?(x, y)
  2162. passables.push([x, y])
  2163. end}}
  2164. # random possibnle coordinates on the map
  2165. return passables[rand(passables.size)]
  2166. end
  2167. #--------------------------------------------------------------------------
  2168. # check_special_states
  2169. # Checks for several Tons of Add-ons effects.
  2170. #--------------------------------------------------------------------------
  2171. def check_special_states
  2172. # if Tons of Add-ons is there
  2173. if $tons_version != nil
  2174. # if version is sufficient and using Auto-Revive
  2175. if $tons_version >= 1.6 && $game_system.AUTO_REVIVE
  2176. # for each actor
  2177. $BlizzABS.battlers.each {|actor|
  2178. # if battler exists and dead and having Auto-Revive
  2179. if actor.battler != nil && actor.battler.hp == 0 &&
  2180. AUTO_REVIVE_IDS.any? {|i| actor.battler.states.include?(i)}
  2181. # execute
  2182. actor.battler.hp += actor.battler.maxhp / 5
  2183. # remove Auto-Revive and Dead
  2184. (AUTO_REVIVE_IDS + [DEAD_ID]).each {|i|
  2185. actor.battler.remove_state(i)}
  2186. # set animation
  2187. actor.animation_id = REVIVE_ANIMATION_ID
  2188. # set revival text
  2189. actor.battler.damage = REVIVE_TEXT
  2190. # display text
  2191. actor.battler.damage_pop = true
  2192. end}
  2193. end
  2194. # if version is sufficient and using Fury Status
  2195. if $tons_version >= 6.41 && $game_system.FURY_STATUS
  2196. # execute Fury Status change
  2197. BlizzCFG.fury_execution
  2198. end
  2199. end
  2200. end
  2201. #--------------------------------------------------------------------------
  2202. # pixel
  2203. # Safe method to retreive the pixel movement rate.
  2204. # (how many movement tiles fit into a 32x32 tile)
  2205. #--------------------------------------------------------------------------
  2206. def pixel
  2207. return ($game_system == nil ? 1 : 2 ** $game_system.pixel_rate)
  2208. end
  2209. #--------------------------------------------------------------------------
  2210. # init_caterpillar
  2211. # Serves for initialization of the caterpillar.
  2212. #--------------------------------------------------------------------------
  2213. def init_caterpillar
  2214. # add player controlled character
  2215. @actors = [$game_player]
  2216. # MAX-PARTY size - 1 times create actor
  2217. (1...Config::MAX_PARTY).each {|i| @actors.push(Map_Actor.new(i))}
  2218. # refresh all battlers
  2219. $game_player.refresh
  2220. # if not very beginning of the game
  2221. if $game_map.map_id != nil && $game_map.map_id > 0
  2222. # move all actors to the player's position
  2223. $game_player.moveto($game_player.x / pixel, $game_player.y / pixel)
  2224. end
  2225. end
  2226. #--------------------------------------------------------------------------
  2227. # can_execute?
  2228. # ch - the character in action
  2229. # target - target
  2230. # act - action data
  2231. # Returns whether a target is in attack/skill/item range.
  2232. #--------------------------------------------------------------------------
  2233. def can_execute?(ch, target = false, act = false)
  2234. # no if paralyzed or charging
  2235. return false if ch.restriction == 4
  2236. # argument correction
  2237. act = ch.ai.act if act == false
  2238. target = ch.ai.target if target == false
  2239. # stop if defend action
  2240. return true if act.defend?
  2241. # stop if no target exists or target is invalid
  2242. return false if target == nil || !target.valid?
  2243. # if attack
  2244. if act.attack?
  2245. # target enemy and non-dead
  2246. enemy, dead = true, false
  2247. else
  2248. # get scope
  2249. scope = (act.skill? ? $data_skills : $data_items)[act.id].scope
  2250. # execute allowed if targeting self
  2251. return true if scope == 0 || scope == 7
  2252. # determine target alignment, dead flag and all flag
  2253. enemy, dead, all = $BlizzABS.util.get_scope_data(scope)
  2254. end
  2255. # temporary variables
  2256. ai, d = ch.ai, act.range
  2257. # determine whether actor or enemy for easier reference
  2258. if ch.is_a?(Map_Actor)
  2259. # decide target group
  2260. group = (ch != $game_player && ((ch.restriction == 3) == enemy)) ?
  2261. ai.positive : ai.negative
  2262. else
  2263. # determine target class group on confusion
  2264. group = (((ch.restriction == 3) == enemy) ? ai.positive : ai.negative)
  2265. end
  2266. # if attack
  2267. if act.attack?
  2268. # get attack affection area
  2269. area = $BlizzABS.util.get_attack_area(ch, d, act.type)
  2270. else
  2271. # get skill/item affection area
  2272. area = $BlizzABS.util.get_skillitem_area(ch, d, act.type, scope)
  2273. end
  2274. # can target be hit considering all conditions
  2275. return ((dead == target.battler.dead?) && @util.intersection(area,
  2276. target.hitbox))
  2277. end
  2278. #--------------------------------------------------------------------------
  2279. # attack_process
  2280. # ch - the character in action
  2281. # Processes ABS attack setup and handling for actors and enemies.
  2282. #--------------------------------------------------------------------------
  2283. def attack_process(ch)
  2284. # temporary variable
  2285. ai = ch.ai
  2286. # determine whether actor or enemy for easier reference
  2287. if ch.is_a?(Map_Actor)
  2288. # decide target group
  2289. group = ((ch != $game_player && ch.restriction == 3)) ?
  2290. ai.positive : ai.negative
  2291. # determine range
  2292. d = Weapons.range(ch.battler.weapon_id)
  2293. d = 1 if d < 1
  2294. # determine type
  2295. type = Weapons.type(ch.battler.weapon_id)
  2296. # determine charge
  2297. charge = Weapons.charge(ch.battler.weapon_id)
  2298. # determine projectile speed
  2299. projectile_speed = Weapons.projectile_speed(ch.battler.weapon_id)
  2300. else
  2301. # determine target group depending on confusion
  2302. group = (ch.restriction == 3 ? ai.positive : ai.negative)
  2303. # determine range
  2304. d = Enemies.range(ch.battler_id)
  2305. d = 1 if d < 1
  2306. # determine type
  2307. type = Enemies.type(ch.battler_id)
  2308. # determine charge
  2309. charge = Enemies.charge(ch.battler_id)
  2310. # determine charge
  2311. charge[0] = BlizzABS::CHARGEMove if charge[0] == BlizzABS::CHARGETrigger
  2312. # determine projectile speed
  2313. projectile_speed = Weapons.projectile_speed(ch.battler_id)
  2314. end
  2315. # if item shooting type
  2316. if type == BOW_ARROW
  2317. # temporary variable
  2318. ids = Weapons.consume(ch.battler.weapon_id)
  2319. # if no more items
  2320. if !ids.include?(ch.battler.item) ||
  2321. $game_party.item_number(ch.battler.item) == 0
  2322. # can't use
  2323. return false
  2324. end
  2325. end
  2326. # if not charging already
  2327. if charge[0] != CHARGENone && !ch.charging?
  2328. # setup charging
  2329. ch.setup_charge(ch, charge)
  2330. # not used yet
  2331. return false
  2332. end
  2333. # create affection area depending on attack type
  2334. case type
  2335. when SWORD, SPEAR, FLAIL # sword attack
  2336. # get attack affection area
  2337. area = $BlizzABS.util.get_attack_area(ch, d, type)
  2338. when BOOMERANG # returning projectile attack
  2339. # decide spriteset
  2340. spriteset = ch.is_a?(Map_Actor) ?
  2341. BlizzABS::SPRProjWeapon + ch.battler.weapon_id.to_s :
  2342. BlizzABS::SPRProjEnemy + ch.battler_id.to_s
  2343. # create returning projectile
  2344. proj = Map_Projectile.new(spriteset, ch, 0, d, projectile_speed,
  2345. REMReturning, group)
  2346. when BOW # projectile attack
  2347. # decide spriteset
  2348. spriteset = ch.is_a?(Map_Actor) ?
  2349. BlizzABS::SPRProjWeapon + ch.battler.weapon_id.to_s :
  2350. BlizzABS::SPRProjEnemy + ch.battler_id.to_s
  2351. # create returning projectile
  2352. proj = Map_Projectile.new(spriteset, ch, 0, d, projectile_speed,
  2353. REMNormal, group)
  2354. when BOW_ARROW # item consuming projectile
  2355. # remove one item from inventory
  2356. $game_party.lose_item(ch.battler.item, 1)
  2357. # temporary variable
  2358. item = $data_items[ch.battler.item]
  2359. # get item explosion data
  2360. explode = Items.type(item.id)
  2361. # if explosion exists
  2362. if explode[1] != EXPLNone
  2363. # fix the missing explosion animation error
  2364. explode[2] = 0 if explode[2] == nil
  2365. # create projectile from exploding item with weapon attack effect
  2366. proj = Map_Projectile.new(BlizzABS::SPRProjItem + item.id.to_s, ch,
  2367. item.id, d, projectile_speed, REMShotItem, group, false,
  2368. explode[1, 3])
  2369. else
  2370. # create projectile from item with weapon attack effect
  2371. proj = Map_Projectile.new(BlizzABS::SPRProjItem + item.id.to_s, ch,
  2372. item.id, d, projectile_speed, REMShotItem, group)
  2373. end
  2374. when SHURIKEN # self consuming weapon
  2375. # temporary variable
  2376. weapon = $data_weapons[ch.battler.weapon_id]
  2377. # unequip last weapon if no more weapons in inventory
  2378. ch.battler.equip(0, 0) if $game_party.weapon_number(weapon.id) == 0
  2379. # remove one weapon from inventory
  2380. $game_party.lose_weapon(weapon.id, 1)
  2381. # self shooting weapon, create projectile from weapon
  2382. proj = Map_Projectile.new(BlizzABS::SPRProjWeapon + weapon.id.to_s, ch,
  2383. weapon.id, d, projectile_speed, REMShotWeapon, group)
  2384. end
  2385. # if projectile fired
  2386. if proj != nil
  2387. # add projectile to buffer
  2388. $BlizzABS.cache.remotes.push(proj)
  2389. # used
  2390. return true
  2391. end
  2392. # iterate through all battlers
  2393. ($game_map.battlers + $BlizzABS.battlers).each {|battler|
  2394. # if target can be hit considering all conditions
  2395. if battler.battler != nil && group.include?(battler.ai.group) &&
  2396. !battler.battler.dead? && @util.intersection(area,
  2397. battler.hitbox)
  2398. # execute attack
  2399. battler.attack_effect(ch, ch.battler)
  2400. # clear damage displays
  2401. battler.battler.damage, battler.battler.damage_pop = nil, false
  2402. end}
  2403. # enemies were attacked
  2404. return true
  2405. end
  2406. #--------------------------------------------------------------------------
  2407. # skillitem_process
  2408. # ch - the skill/item using character
  2409. # object - the skill or item that is being used
  2410. # Processes skill and item use in Blizz-ABS on the map. One method is
  2411. # used for both since the process is almost identical for both objects.
  2412. #--------------------------------------------------------------------------
  2413. def skillitem_process(ch, object)
  2414. # determine whether skill or item for easier reference
  2415. case object
  2416. when RPG::Skill
  2417. skill, d, time = true, Skills.range(object.id), Skills.trap(object.id)
  2418. type, charge = Skills.type(object.id), Skills.charge(object.id)
  2419. projectile_speed = Skills.projectile_speed(object.id)
  2420. spriteset = BlizzABS::SPRProjSkill
  2421. when RPG::Item
  2422. skill, d, time = false, Items.range(object.id), Items.trap(object.id)
  2423. type, charge = Items.type(object.id), Items.charge(object.id)
  2424. projectile_speed = Items.projectile_speed(object.id)
  2425. spriteset = BlizzABS::SPRProjItem
  2426. end
  2427. # fix the missing explosion animation error
  2428. type[2] = 0 if type[1] != EXPLNone && type[2] == nil
  2429. # if enemy
  2430. if ch.is_a?(Map_Enemy) && charge[0] == CHARGETrigger
  2431. # correct charge type
  2432. charge[0] = CHARGEMove
  2433. end
  2434. # if not charging already and no selection data
  2435. if charge[0] != CHARGENone && !ch.charging? &&
  2436. $game_temp.select_data == nil
  2437. # setup charging
  2438. ch.setup_charge(object, charge)
  2439. # not used yet
  2440. return false
  2441. end
  2442. # if summoning
  2443. if type[0] == SUMMON
  2444. # nobody except actors can summon with caterpillar turned on
  2445. return false unless ch.is_a?(Map_Actor) && $game_system.caterpillar
  2446. # get summoning data
  2447. summon = (skill ? Skills.summon(object.id) : Items.summon(object.id))
  2448. # if summon ID or time is 0
  2449. if summon[0] == SUMMONNone || summon[1] == 0 || summon[2] == 0
  2450. # no summoning
  2451. return false
  2452. end
  2453. # no summoning if already summoned
  2454. return false if (@pets + @monsters).any? {|b| b.battler_id == summon[1]}
  2455. # if any summon limit reached
  2456. if summon[0] == SUMMONPet && @pets.size >= BlizzABS::Config::MAX_PETS ||
  2457. summon[0] == SUMMONMonster &&
  2458. @monsters.size >= BlizzABS::Config::MAX_MONSTERS ||
  2459. @pets.size + @monsters.size >= BlizzABS::Config::MAX_SUMMONS
  2460. # no summoning
  2461. return false
  2462. end
  2463. # create new map actor
  2464. new_battler = Map_Actor.new(summon[1])
  2465. # if pet
  2466. if summon[0] == SUMMONPet
  2467. # summon pet
  2468. summon_pet(new_battler, summon[2])
  2469. # if monster
  2470. elsif summon[0] == SUMMONMonster
  2471. # summon monster
  2472. summon_monster(new_battler, summon[2])
  2473. else
  2474. # something's not right here, no summoning
  2475. return false
  2476. end
  2477. # get pixel movement rate
  2478. pix = $BlizzABS.pixel
  2479. # move to correct position
  2480. new_battler.moveto(ch.x / pix, ch.y / pix)
  2481. # set correct battler
  2482. new_battler.battler = $game_actors[summon[1]]
  2483. # heal the battler completely
  2484. new_battler.battler.recover_all
  2485. # return to caterpillar first
  2486. new_battler.cindex, new_battler.ai.state = nil, AI::Return
  2487. # refresh display
  2488. new_battler.refresh
  2489. # set animation
  2490. new_battler.animation_id = object.animation2_id
  2491. # summon successful
  2492. return true
  2493. end
  2494. # skill/item used (can be a common event call) if no target scope
  2495. return true if object.scope == 0
  2496. # if targeting self
  2497. if object.scope == 7
  2498. # if skill
  2499. if skill
  2500. # execute skill upon user
  2501. ch.skill_effect(ch, ch.battler, object)
  2502. # check special skill effects
  2503. self.check_special_skills(ch, [ch], object)
  2504. else
  2505. # execute item upon user
  2506. ch.item_effect(ch, ch.battler, object)
  2507. end
  2508. # clear damage displays
  2509. ch.battler.damage, ch.battler.damage_pop = nil, false
  2510. # skill/item used
  2511. return true
  2512. end
  2513. # correct range
  2514. d = 1 if d < 1
  2515. # determine target alignment, dead flag and all flag
  2516. enemy, dead, all = $BlizzABS.util.get_scope_data(object.scope)
  2517. # doesn't target all and no death roulette initially
  2518. target_all = false
  2519. # if Tons is there and skill process
  2520. if $tons_version != nil && $tons_version >= 6.02 && skill
  2521. # if version is correct and Target 'em all! is being used for this skill
  2522. if $game_system.TARGET_EM_ALL && FULL_TARGET_IDS.include?(object.id)
  2523. # targets all and forces all flag
  2524. target_all = all = true
  2525. end
  2526. end
  2527. # temporary variable
  2528. ai = ch.ai
  2529. # determine whether actor or enemy for easier reference
  2530. if ch.is_a?(Map_Actor)
  2531. # decide target group
  2532. group = (((ch == $game_player || ch.restriction != 3) == enemy) ?
  2533. ai.negative : ai.positive)
  2534. else
  2535. # determine target group depending on confusion
  2536. group = (((ch.restriction == 3) == enemy) ? ai.positive : ai.negative)
  2537. end
  2538. # selection only if player using selectable skill/item and not charging
  2539. if ch == $game_player && $game_temp.select_data == nil &&
  2540. (charge[0] == CHARGENone || charge[0] != CHARGENone &&
  2541. ch.charged?) && (target_all || type[0] == HOMING ||
  2542. type[0] == DIRECT || type[0] == BEAM && all)
  2543. # temporary variable, selection skill/item
  2544. handling = 0
  2545. else
  2546. # set handling for projectile skill/item or direct skill/item
  2547. handling = ((type[0] == SHOOT || type[0] == HOMING ||
  2548. type[0] == TRAP || type[0] == TIMED) ? 1 : 2)
  2549. end
  2550. # depending on handling
  2551. case handling
  2552. when 0 # selection
  2553. # create circle shape data
  2554. area = $BlizzABS.util.get_circle_area(ch, d)
  2555. # create fullscreen rectangle
  2556. screen = $BlizzABS.util.get_fullscreen_area
  2557. # no use if scene not Scene_Map or spriteset doesn't exist
  2558. return false if !$scene.is_a?(Scene_Map) || $scene.spriteset == nil
  2559. # get all selectable map battlers
  2560. available = $scene.spriteset.character_sprites.find_all {|sprite|
  2561. sprite.character.is_a?(Map_Battler) &&
  2562. !sprite.character.is_a?(Map_Remote) &&
  2563. group.include?(sprite.character.ai.group) &&
  2564. can_be_hit(sprite.character, dead, type, all, screen, area)}
  2565. # no use if no selectable targets
  2566. return false if available.size == 0
  2567. # sort selectable targets by coordinates
  2568. available.sort {|a, b| b.y > a.y ? 1 : b.y < a.y ? -1 : (b.x <=> a.x)}
  2569. # setup select interuption
  2570. $game_temp.select_data = [object, d * 32, type[0], available]
  2571. # don't use skill/item yet
  2572. return false
  2573. when 1 # projectile
  2574. # decide process branch depending on skill type
  2575. case type[0]
  2576. # set normal or break-through projectile data
  2577. when SHOOT
  2578. # if break-through
  2579. if all
  2580. # set break-through projectile skill or item
  2581. projectype = (skill ? REMBreakSkill : REMBreakSkill)
  2582. else
  2583. # set normal projectile skill or item
  2584. projectype = (skill ? REMNormalSkill : REMNormalItem)
  2585. end
  2586. # set range
  2587. targets = [d]
  2588. # homing skill/item
  2589. when HOMING
  2590. # get circle area
  2591. area = $BlizzABS.util.get_circle_area(ch, d)
  2592. # create fullscreen rectangle
  2593. screen = $BlizzABS.util.get_fullscreen_area
  2594. # get all targets that can be hit
  2595. targets = ($game_map.battlers + $BlizzABS.battlers).find_all {|b|
  2596. can_be_hit(b, dead, type, all, screen, area)}
  2597. # if targetting everybody
  2598. if target_all
  2599. # reflection possible on everybody
  2600. other = targets.clone
  2601. else
  2602. # reflection possible on non-target group
  2603. other = targets.find_all {|b| !group.include?(b.ai.group)}
  2604. # if predefined target exists
  2605. if !all && ai.target != nil
  2606. # set predefined target
  2607. targets = [ai.target]
  2608. else
  2609. # set possible targets
  2610. targets = targets.find_all {|b| group.include?(b.ai.group)}
  2611. end
  2612. end
  2613. # set homing projectile type
  2614. projectype = (skill ? REMInitSkill : REMInitItem)
  2615. # homing skill/item
  2616. when TRAP
  2617. # targets for selection, other targets
  2618. targets, other = [], []
  2619. # set homing projectile type
  2620. projectype = (skill ? REMTrapSkill : REMTrapItem)
  2621. # homing skill/item
  2622. when TIMED
  2623. # targets for selection, other targets
  2624. targets, other = [], []
  2625. # set homing projectile type
  2626. projectype = (skill ? REMTimedSkill : REMTimedItem)
  2627. end
  2628. when 2 # direct
  2629. # if direct skill or shockwave skill
  2630. if type[0] == DIRECT
  2631. # get circle area
  2632. area = $BlizzABS.util.get_circle_area(ch, d)
  2633. # if beam skill (fullscreen skill that does not target all)
  2634. elsif !all
  2635. # get affection area rectangle
  2636. area = $BlizzABS.util.get_front_area(ch, d)
  2637. # initialize
  2638. this = nil
  2639. # if scene is Scene_Map and spriteset exists
  2640. if $scene.is_a?(Scene_Map) && $scene.spriteset != nil
  2641. # find the sprite of this character
  2642. $scene.spriteset.character_sprites.each {|spr|
  2643. if spr.character == ch
  2644. this = spr
  2645. break
  2646. end}
  2647. end
  2648. # if sprite exists
  2649. if this != nil
  2650. # create sprite
  2651. sprite = Sprite.new($scene.spriteset.viewport1)
  2652. # try to
  2653. begin
  2654. # load the characterset file
  2655. sprite.bitmap = RPG::Cache.character(object.icon_name, 0)
  2656. # temporary variables
  2657. w1, h = sprite.bitmap.width, sprite.bitmap.height
  2658. # if failed
  2659. rescue
  2660. # get width and height
  2661. w1, h = 24, d*32
  2662. # create bitmap
  2663. sprite.bitmap = Bitmap.new(w1, h)
  2664. # get image from cache
  2665. b = $BlizzABS.cache.image('beam1')
  2666. # copy the beam image
  2667. (0...h).each {|i|
  2668. a = (i < h/2 ? i**2*2 : (h-i-1)**2*2)
  2669. a = 255 if a > 255
  2670. sprite.bitmap.blt(0, i, b, Rect.new(0, 0, b.width, b.height), a)}
  2671. end
  2672. w2 = case ch.direction
  2673. when 6 then 16-w1/2
  2674. else
  2675. w1/2+16
  2676. end
  2677. # set sprite position, rotation and offsets depending on facing
  2678. case ch.direction
  2679. when 2
  2680. sprite.angle, sprite.ox = 0, w1/2
  2681. sprite.x, sprite.y, sprite.z = this.x, this.y, this.z+1
  2682. when 4
  2683. sprite.angle, sprite.ox, sprite.oy = 270, w2, w1/2+16
  2684. sprite.x, sprite.y, sprite.z = this.x-w1-16, this.y, this.z-1
  2685. when 6
  2686. sprite.angle, sprite.ox, sprite.oy = 90, -w2, -w1/2+16
  2687. sprite.x, sprite.y, sprite.z = this.x+16, this.y, this.z-1
  2688. when 8
  2689. sprite.angle, sprite.ox, sprite.oy = 180, w1/2, h+16
  2690. sprite.x, sprite.y, sprite.z = this.x, this.y-h-32, this.z-32
  2691. end
  2692. # add sprite for handling
  2693. $BlizzABS.cache.beams.push([sprite, 20])
  2694. # set beam flag
  2695. beam = true
  2696. end
  2697. end
  2698. # create fullscreen rectangle
  2699. screen = $BlizzABS.util.get_fullscreen_area
  2700. # get all targets that can be hit
  2701. targets = ($game_map.battlers + $BlizzABS.battlers).find_all {|b|
  2702. can_be_hit(b, dead, type, all, screen, area)}
  2703. # if targetting everybody
  2704. if target_all
  2705. # reflection possible on everybody
  2706. other = targets.clone
  2707. else
  2708. # reflection possible on non-target group
  2709. other = targets.find_all {|b| !group.include?(b.ai.group)}
  2710. # if predefined target exists
  2711. if !all && ai.target != nil
  2712. # set predefined target
  2713. targets = [ai.target]
  2714. else
  2715. # set possible targets
  2716. targets = targets.find_all {|b| group.include?(b.ai.group)}
  2717. end
  2718. end
  2719. end
  2720. # if no selectable targets and not trap
  2721. if targets.size == 0 && projectype != REMTrapSkill &&
  2722. projectype != REMTrapItem && projectype != REMTimedSkill &&
  2723. projectype != REMTimedItem
  2724. # no use
  2725. return (beam == true)
  2726. end
  2727. # if Full Reflection System is being used and not breaking reflection skill
  2728. if $full_reflection_system != nil && $full_reflection_system >= 3.01 &&
  2729. targets[0].is_a?(Map_Battler) && skill && !beam &&
  2730. !BlizzCFG::BREAK_REFLECT.include?(object.id) &&
  2731. projectype != REMTrapSkill && projectype != REMTrapItem &&
  2732. projectype != REMTimedSkill && projectype != REMTimedItem
  2733. # execute reflection effect in Blizz-ABS
  2734. BlizzCFG.reflection_effect_blizzabs(ch, targets, other, object)
  2735. end
  2736. # get a random target if not targeting all and no beam or death roulette
  2737. targets = [targets[rand(targets.size)]] if !all && !beam
  2738. # if projectile data is available and projectile should be created
  2739. if projectype != nil
  2740. # temporary variable
  2741. explode = (type[1] != EXPLNone ? type[1, 3] : nil)
  2742. # if trap
  2743. if projectype == REMTrapSkill || projectype == REMTrapItem
  2744. # create trap
  2745. proj = Map_Trap.new(spriteset + object.id.to_s, ch, object.id, d,
  2746. time, projectype, group, dead, explode)
  2747. # add trap to buffer
  2748. $BlizzABS.cache.remotes.push(proj)
  2749. # if timed trap
  2750. elsif projectype == REMTimedSkill || projectype == REMTimedItem
  2751. # create timed trap
  2752. proj = Map_Timed.new(spriteset + object.id.to_s, ch, object.id, d,
  2753. time, projectype, group, dead, explode)
  2754. # add timed trap to buffer
  2755. $BlizzABS.cache.remotes.push(proj)
  2756. else
  2757. # iterate through all targets
  2758. targets.each {|target|
  2759. # create projectile
  2760. proj = Map_Projectile.new(spriteset + object.id.to_s, ch,
  2761. object.id, target, projectile_speed, projectype, group, dead,
  2762. explode)
  2763. # add projectile to buffer
  2764. $BlizzABS.cache.remotes.push(proj)}
  2765. end
  2766. # if skill
  2767. elsif skill
  2768. # execute skill effect upon all targets
  2769. targets.each {|target| target.skill_effect(ch, ch.battler, object)}
  2770. # check special skill effects
  2771. self.check_special_skills(ch, targets, object)
  2772. # clear damage displays upon all targets
  2773. targets.each {|target|
  2774. target.battler.damage, target.battler.damage_pop = nil, false}
  2775. else
  2776. # upon all targets
  2777. targets.each {|target|
  2778. # execute item effect
  2779. target.item_effect(ch, ch.battler, object)
  2780. # clear damage displays
  2781. target.battler.damage, target.battler.damage_pop = nil, false}
  2782. end
  2783. # skill/item use successful
  2784. return true
  2785. end
  2786. #--------------------------------------------------------------------------
  2787. # can_be_hit
  2788. # char - current map battler
  2789. # dead - dead flag
  2790. # type - object type
  2791. # all - targeting all
  2792. # screen - screen rectangle
  2793. # area - affection area data
  2794. # Determines whether a map battler is affected by an area.
  2795. #--------------------------------------------------------------------------
  2796. def can_be_hit(char, dead, type, all, screen, area)
  2797. return (char.battler != nil && dead == char.battler.dead? &&
  2798. @util.intersection(screen, char.hitbox) && (type[0] == BEAM && all ||
  2799. @util.intersection(area, char.hitbox)))
  2800. end
  2801. #--------------------------------------------------------------------------
  2802. # check_special_skills(battler, targets, skill)
  2803. # ch - the character
  2804. # targets - all targets
  2805. # skill - the used skill
  2806. # Addition to process special skill effects.
  2807. #--------------------------------------------------------------------------
  2808. def check_special_skills(ch, targets, skill)
  2809. # if Tons of Add-ons is being used
  2810. if $tons_version != nil && $tons_version >= 6.4
  2811. # damage sprite character
  2812. dmgchar = (ch.body == nil ? ch : ch.body)
  2813. # if using absorbing skills
  2814. if $game_system.ABSORB_HP_SP
  2815. # set damage accumulation to 0
  2816. damages = 0
  2817. # if skill absorbs HP
  2818. if SKILL_IDS_HP.include?(skill.id)
  2819. # for each target
  2820. targets.each {|target|
  2821. # if damage was done
  2822. if target.battler.damage.is_a?(Numeric)
  2823. # accumulate damage
  2824. damages += target.battler.damage
  2825. end}
  2826. # change battler HP
  2827. ch.battler.hp += damages
  2828. # request damage sprite
  2829. $BlizzABS.util.request_damage_sprite(dmgchar)
  2830. # if skill absorbs SP
  2831. elsif SKILL_IDS_SP.include?(skill.id)
  2832. # for each target
  2833. targets.each {|target|
  2834. # if damage was done
  2835. if target.battler.damage.is_a?(Numeric)
  2836. # accumulate damage
  2837. damages += target.battler.spdamage
  2838. # remove damage
  2839. target.battler.damage = nil
  2840. # make SP damage text
  2841. target.check_spdamage
  2842. end}
  2843. # change battler SP
  2844. ch.battler.sp += damages
  2845. # request damage sprite
  2846. $BlizzABS.util.request_damage_sprite(dmgchar)
  2847. end
  2848. end
  2849. # if using Destructor Skill and battler should die
  2850. if $game_system.DESTRUCTOR_SKILL && ch.battler.set_to_die
  2851. # kill
  2852. ch.battler.hp = 0
  2853. end
  2854. # if using Blus Magic Skills
  2855. if $game_system.BLUE_MAGIC_SKILL && BLUE_MAGIC_IDS.include?(skill.id)
  2856. # remove damage for all targets
  2857. targets.each {|target| target.battler.damage = nil}
  2858. # get a random target
  2859. target = targets[rand(targets.size)]
  2860. # try to learn
  2861. if rand(100) < skill.hit
  2862. # if enemy
  2863. if target.battler.is_a?(Game_Enemy)
  2864. # initialize array
  2865. ids = []
  2866. # get all skill IDs of the target
  2867. target.battler.actions.each {|act|
  2868. ids.push(act.skill_id) if act.kind == 1}
  2869. # if actor
  2870. elsif target.battler.is_a?(Game_Actor)
  2871. # get all skill IDs of the target
  2872. ids = target.battler.skills.clone
  2873. end
  2874. # if any ID exists
  2875. if ids.size > 0
  2876. # get skill
  2877. newskill = $data_skills[ids[rand(ids.size)]]
  2878. # if already knowing that skill
  2879. if ch.battler.skills.include?(newskill.id)
  2880. # make damage text
  2881. target.battler.damage = "#{newskill.name} known"
  2882. else
  2883. # learn skill
  2884. target.battler.learn_skill(newskill.id)
  2885. # make damage text
  2886. target.battler.damage = "#{newskill.name} learned"
  2887. end
  2888. else
  2889. # no skills available
  2890. target.battler.damage = 'None available'
  2891. end
  2892. else
  2893. # not successful
  2894. target.battler.damage = 'Miss'
  2895. end
  2896. end
  2897. end
  2898. end
  2899. #--------------------------------------------------------------------------
  2900. # drop_event
  2901. # items - array of items which the event contains
  2902. # real_x - real x-coordinate
  2903. # real_y - real y-coordinate
  2904. # dropper - the enemy that dropped the loot
  2905. # time - timer setting
  2906. # Creates an event that contains loot that can be picked up.
  2907. #--------------------------------------------------------------------------
  2908. def drop_event(items, real_x, real_y, dropper = nil, time = nil)
  2909. # map coordinates
  2910. x, y, icon = real_x / 128, real_y / 128, false
  2911. # if gold dropped and no corpses used
  2912. if dropper == nil && items[0].is_a?(Numeric) &&
  2913. !BlizzABS::Config::CORPSES
  2914. # set up everything for map display
  2915. event = create_drop_event(x, y, BlizzABS::Config::GOLD_DROP)
  2916. # setup the event commands
  2917. setup_drop_event(event, items, BlizzABS::Config::GOLD_PICKUP_SOUND_FILE)
  2918. else
  2919. # if not dropped by enemy
  2920. if dropper == nil
  2921. # create drop event with icon spriteset
  2922. event = create_drop_event(x, y, items[0].icon_name)
  2923. # event with icon spriteset
  2924. icon = !Items.drop_sprite(items[0].id)
  2925. # if using corpses
  2926. elsif BlizzABS::Config::CORPSES
  2927. # create drop event
  2928. event = create_drop_event(x, y, dropper.character_name_org +
  2929. BlizzABS::SPRCorpse, dropper.character_hue, 0)
  2930. else
  2931. # create drop event
  2932. event = create_drop_event(x, y, dropper.character_name_org,
  2933. dropper.character_hue)
  2934. end
  2935. # setup the event commands
  2936. setup_drop_event(event, items)
  2937. end
  2938. # call superclass method
  2939. drop = Game_Event.new($game_map.map_id, event)
  2940. # mark created event as icon event
  2941. drop.icondrop = icon
  2942. # refresh
  2943. drop.refresh
  2944. # set up drop mode
  2945. drop.activate_drop_mode(BlizzABS::Config::DROP_TIME * 40)
  2946. # add into map events
  2947. $game_map.events[event.id] = drop
  2948. # stop if scene not Scene_Map or spriteset doesn't exist
  2949. return if !$scene.is_a?(Scene_Map) || $scene.spriteset == nil
  2950. # create own sprite as dropped
  2951. sprite = Sprite_Character.new($scene.spriteset.viewport1, drop)
  2952. # add to spriteset handler
  2953. $scene.spriteset.character_sprites.push(sprite)
  2954. end
  2955. #--------------------------------------------------------------------------
  2956. # create_drop_event
  2957. # x - x-coordinate
  2958. # y - y-coordinate
  2959. # character_name - spriteset name
  2960. # character_hue - spriteset hue
  2961. # trigger - event trigger
  2962. # Sets up everything so the item can be displayed correctly.
  2963. #--------------------------------------------------------------------------
  2964. def create_drop_event(x, y, character_name, character_hue = 0, trigger = 1)
  2965. # create new event
  2966. event = RPG::Event.new(0, 0)
  2967. # if no floor beneath
  2968. if BlizzABS::Config::NO_FLOOR_TAGS.include?($game_map.terrain_tag(x, y))
  2969. # find closest coordinates that have a floor
  2970. event.x, event.y = $BlizzABS.util.closest_floor(x, y)
  2971. else
  2972. # set coordinates
  2973. event.x, event.y = x, y
  2974. end
  2975. # get keys
  2976. keys = $game_map.events.keys
  2977. # set new ID
  2978. event.id = (keys.size == 0 ? 1 : keys.max + 1)
  2979. # set own event name DROP + ID
  2980. event.name = "DROP#{event.id}"
  2981. # set up all necessary event page settings
  2982. event.pages[0].graphic.character_name = character_name
  2983. event.pages[0].graphic.character_hue = character_hue
  2984. event.pages[0].through = event.pages[0].direction_fix = true
  2985. event.pages[0].walk_anime = event.pages[0].step_anime = false
  2986. event.pages[0].trigger = trigger
  2987. # return the created event
  2988. return event
  2989. end
  2990. #--------------------------------------------------------------------------
  2991. # setup_drop_event
  2992. # event - the event
  2993. # items - the dropped items
  2994. # soundfile - the sound file to be played
  2995. # Sets up everything so that the right items are obtained when picking up
  2996. # the event.
  2997. #--------------------------------------------------------------------------
  2998. def setup_drop_event(event, items,
  2999. soundfile = BlizzABS::Config::ITEM_PICKUP_SOUND_FILE)
  3000. # if there are no items
  3001. if items.size == 0
  3002. # create the event commands
  3003. event.pages[0].list.push(RPG::EventCommand.new)
  3004. # erase event command
  3005. event.pages[0].list[0].code = 116
  3006. # abort
  3007. return
  3008. end
  3009. # create the event commands
  3010. (items.size + 2).times {event.pages[0].list.push(RPG::EventCommand.new)}
  3011. # play sound effect
  3012. event.pages[0].list[items.size].code = 250
  3013. # set file to be played
  3014. event.pages[0].list[items.size].parameters = [soundfile]
  3015. # erase event command
  3016. event.pages[0].list[items.size + 1].code = 116
  3017. # for each dropped item
  3018. items.each_index {|i|
  3019. # deteremine code and parameters
  3020. case items[i]
  3021. when Numeric then code, parameters = 125, [0, 0, items[i]]
  3022. when RPG::Item then code, parameters = 126, [items[i].id, 0, 0, 1]
  3023. when RPG::Weapon then code, parameters = 127, [items[i].id, 0, 0, 1]
  3024. when RPG::Armor then code, parameters = 128, [items[i].id, 0, 0, 1]
  3025. end
  3026. # which event command
  3027. event.pages[0].list[i].code = code
  3028. # increase quantity by number command
  3029. event.pages[0].list[i].parameters = parameters}
  3030. end
  3031. #--------------------------------------------------------------------------
  3032. # get_enemies
  3033. # id - event ID or false for troop
  3034. # Gets the requested target enemies.
  3035. #--------------------------------------------------------------------------
  3036. def get_enemies(id)
  3037. # get targets
  3038. return (id ? [$game_map.events[id]].compact : $game_map.battlers)
  3039. end
  3040. #--------------------------------------------------------------------------
  3041. # get_actors
  3042. # id - party position ID or false for party
  3043. # Gets the requested target actors.
  3044. #--------------------------------------------------------------------------
  3045. def get_actors(id)
  3046. # get targets
  3047. return (id ? [$BlizzABS.actors[id]].compact : $BlizzABS.actors.clone)
  3048. end
  3049. #--------------------------------------------------------------------------
  3050. # get_targets
  3051. # target_type - enemies or actors
  3052. # target - which target
  3053. # Gets the requested targets.
  3054. #--------------------------------------------------------------------------
  3055. def get_targets(target_type, target)
  3056. return case target_type
  3057. when ENEMIES then return get_enemies(target)
  3058. when ACTORS then return get_actors(target)
  3059. when NONE then return nil
  3060. end
  3061. end
  3062. #--------------------------------------------------------------------------
  3063. # enemy_change_hp
  3064. # id - event ID or false for troop
  3065. # operation - increase flag
  3066. # operand_type - variable or constant
  3067. # operand - value or variable ID
  3068. # allow_kill - allow to kill
  3069. # Part of the battleflow control on the map and allows users to change the
  3070. # HP of enemies on the map.
  3071. #--------------------------------------------------------------------------
  3072. def enemy_change_hp(id, operation, operand_type, operand, allow_kill)
  3073. # creating an interpreter
  3074. interpreter = Interpreter.new
  3075. # get value from data
  3076. value = interpreter.operate_value(operation, operand_type, operand)
  3077. # for all target enemies
  3078. get_enemies(id).each {|enemy|
  3079. # if actually existing enemy
  3080. if enemy.battler != nil
  3081. # if not allowed to kill and change would kill
  3082. if !allow_kill && enemy.battler.hp <= -value
  3083. # set to 1 HP
  3084. enemy.battler.hp = 1
  3085. else
  3086. # change HP
  3087. enemy.battler.hp += value
  3088. end
  3089. end}
  3090. end
  3091. #--------------------------------------------------------------------------
  3092. # enemy_change_sp
  3093. # id - event ID or false for troop
  3094. # operation - increase flag
  3095. # operand_type - variable or constant
  3096. # operand - value or variable ID
  3097. # Part of the battleflow control on the map and allows users to change the
  3098. # SP of enemies on the map.
  3099. #--------------------------------------------------------------------------
  3100. def enemy_change_sp(id, operation, operand_type, operand)
  3101. # creating an interpreter
  3102. interpreter = Interpreter.new
  3103. # get value from data
  3104. value = interpreter.operate_value(operation, operand_type, operand)
  3105. # change SP of all existing target enemies
  3106. get_enemies(id).each {|e| e.battler.sp += value if e.battler != nil}
  3107. end
  3108. #--------------------------------------------------------------------------
  3109. # enemy_change_state
  3110. # id - event ID or false for troop
  3111. # add - add/remove flag
  3112. # state_id - status effect ID
  3113. # Part of the battleflow control on the map and allows users to change the
  3114. # states of enemies on the map.
  3115. #--------------------------------------------------------------------------
  3116. def enemy_change_state(id, add, state_id)
  3117. # for all target enemies
  3118. get_enemies(id).each {|enemy|
  3119. # if actually existing enemy
  3120. if enemy.battler != nil
  3121. # clear immortal flag if state is dead state
  3122. enemy.battler.immortal = false if $data_states[state_id].zero_hp
  3123. # add or remove state
  3124. add ? enemy.battler.add_state(state_id) :
  3125. enemy.battler.remove_state(state_id)
  3126. end}
  3127. end
  3128. #--------------------------------------------------------------------------
  3129. # enemy_recover_all
  3130. # id - event ID or false for troop
  3131. # Part of the battleflow control on the map and allows users to let
  3132. # enemies recover on the map.
  3133. #--------------------------------------------------------------------------
  3134. def enemy_recover_all(id)
  3135. # recover all existing target enemies
  3136. get_enemies(id).each {|e| e.battler.recover_all if e.battler != nil}
  3137. end
  3138. #--------------------------------------------------------------------------
  3139. # enemy_transform
  3140. # id - event ID or false for troop
  3141. # enemy_id - enemy ID in the database
  3142. # Part of the battleflow control on the map and allows users to transform
  3143. # enemies on the map.
  3144. #--------------------------------------------------------------------------
  3145. def enemy_transform(id, enemy_id)
  3146. # transform all existing target enemies
  3147. get_enemies(id).each {|e| e.transform(enemy_id) if e.battler != nil}
  3148. end
  3149. #--------------------------------------------------------------------------
  3150. # enemy_change_group
  3151. # id - event ID or false for troop
  3152. # group_id - alignment group ID
  3153. # Part of the battleflow control on the map and allows users to change the
  3154. # alignment group of enemies.
  3155. #--------------------------------------------------------------------------
  3156. def enemy_change_group(id, group_id)
  3157. # transform all existing target enemies
  3158. get_enemies(id).each {|e| e.ai.setup_group(group_id) if e.battler != nil}
  3159. end
  3160. #--------------------------------------------------------------------------
  3161. # enemy_affect_group
  3162. # id - event ID or false for troop
  3163. # group_id - alignment group ID
  3164. # Part of the battleflow control on the map and allows users to cause
  3165. # a negative effect on the enemy alignment group from another group.
  3166. #--------------------------------------------------------------------------
  3167. def enemy_affect_group(id, group_id)
  3168. # transform all existing target enemies
  3169. get_enemies(id).each {|e| e.alignment_effect(group_id) if e.battler != nil}
  3170. end
  3171. #--------------------------------------------------------------------------
  3172. # enemy_deal_damage
  3173. # id - event ID or false for troop
  3174. # operand_type - variable or constant
  3175. # operand - value or variable ID
  3176. # Part of the battleflow control on the map and allows users to deal
  3177. # damage to enemies on the map.
  3178. #--------------------------------------------------------------------------
  3179. def enemy_deal_damage(id, operand_type, operand)
  3180. # execute requested command
  3181. battler_deal_damage(get_enemies(id), operand_type, operand)
  3182. end
  3183. #--------------------------------------------------------------------------
  3184. # actor_deal_damage
  3185. # id - actor position ID or false for party
  3186. # operand_type - variable or constant
  3187. # operand - value or variable ID
  3188. # Part of the battleflow control on the map and allows users to deal
  3189. # damage to actors on the map.
  3190. #--------------------------------------------------------------------------
  3191. def actor_deal_damage(id, operand_type, operand)
  3192. # execute requested command
  3193. battler_deal_damage(get_actors(id), operand_type, operand)
  3194. end
  3195. #--------------------------------------------------------------------------
  3196. # battler_deal_damage
  3197. # targets - targets
  3198. # operand_type - variable or constant
  3199. # operand - value or variable ID
  3200. # Deals damage to the given targets.
  3201. #--------------------------------------------------------------------------
  3202. def battler_deal_damage(targets, operand_type, operand)
  3203. # creating an interpreter
  3204. interpreter = Interpreter.new
  3205. # if number
  3206. if operand.is_a?(Numeric)
  3207. # get value from data
  3208. value = interpreter.operate_value(CONSTANT, operand_type, operand)
  3209. else
  3210. # set direct value
  3211. value = operand
  3212. end
  3213. # for all target enemies
  3214. targets.each {|battler|
  3215. # if actually existing battler
  3216. if battler.valid?
  3217. # damage sprite character
  3218. dmgchar = (battler.body == nil ? battler : battler.body)
  3219. # change HP if numeric value
  3220. battler.battler.hp -= value if value.is_a?(Numeric)
  3221. # set damage
  3222. battler.battler.damage = value
  3223. # request damage sprite
  3224. $BlizzABS.util.request_damage_sprite(dmgchar)
  3225. # reset damage
  3226. battler.battler.damage = nil
  3227. # reset hpdamage and spdamage
  3228. battler.battler.hpdamage = battler.battler.spdamage = 0
  3229. end}
  3230. end
  3231. #--------------------------------------------------------------------------
  3232. # enemy_force_action
  3233. # id - event ID or false for troop
  3234. # target_type - enemies or actors
  3235. # target - which target
  3236. # action_type - attack, defend, escape or skill
  3237. # data - defend time, runaway time or skill ID
  3238. # Part of the battleflow control on the map and allows users to enforce
  3239. # enemies to make an action.
  3240. #--------------------------------------------------------------------------
  3241. def enemy_force_action(id, target_type, target, action_type, data)
  3242. # abort if trying to force an enemy to use an item
  3243. return if action_type == ITEM
  3244. # decide targets depending on target battler type
  3245. to_target = get_targets(target_type, target)
  3246. # for all enemies
  3247. get_enemies(id).each {|enemy|
  3248. # if actually existing enemy
  3249. if enemy.battler != nil
  3250. # setup action for enemy
  3251. $BlizzABS.AI.normal_action(enemy, to_target, to_target,
  3252. (action_type < SKILL), action_type, data, data, data,
  3253. (action_type != ITEM), (to_target == NONE), true)
  3254. # make actually aggressive if action exists
  3255. enemy.ai.aggressive = true if enemy.ai.act.valid?
  3256. end}
  3257. end
  3258. #--------------------------------------------------------------------------
  3259. # actor_force_action
  3260. # id - actor position ID or false for party
  3261. # target_type - enemies or actors
  3262. # target - which target
  3263. # action_type - attack, defend, escape or skill
  3264. # data - defend time, skill ID or item ID
  3265. # Part of the battleflow control on the map and allows users to enforce
  3266. # enemies to make an action.
  3267. #--------------------------------------------------------------------------
  3268. def actor_force_action(id, target_type, target, action_type, data)
  3269. # abort if trying to force an actor to run away
  3270. return if action_type == ESCAPE
  3271. # decide targets depending on target battler type
  3272. to_target = get_targets(target_type, target)
  3273. # for all actors
  3274. get_actors(id).each {|actor|
  3275. # if actually existing actor
  3276. if actor.valid?
  3277. # setup action for enemy
  3278. $BlizzABS.AI.normal_action(actor, to_target, to_target,
  3279. (action_type < SKILL), action_type, data, data, data,
  3280. (action_type != ITEM), (to_target == NONE), true)
  3281. end}
  3282. end
  3283. #--------------------------------------------------------------------------
  3284. # get_enemy
  3285. # id - event ID
  3286. # Returns the battler instance of an enemy.
  3287. #--------------------------------------------------------------------------
  3288. def get_enemy(id)
  3289. # get enemies
  3290. enemies = get_enemies(id)
  3291. # return result
  3292. return enemies[0].battler
  3293. end
  3294. #--------------------------------------------------------------------------
  3295. # is_enemy?
  3296. # id - event ID
  3297. # Checks whether the given event is an enemy.
  3298. #--------------------------------------------------------------------------
  3299. def is_enemy?(id)
  3300. # get enemies
  3301. enemies = get_enemies(id)
  3302. # return result
  3303. return (enemies.size > 0 && enemies[0].is_a?(Map_Battler))
  3304. end
  3305. #--------------------------------------------------------------------------
  3306. # enemy_has_state?
  3307. # id - event ID or false for troop
  3308. # s_id - state ID
  3309. # Checks whether the given enemy has a specific state.
  3310. #--------------------------------------------------------------------------
  3311. def enemy_has_state?(id, s_id)
  3312. # get enemies
  3313. enemies = get_enemies(id)
  3314. # return result
  3315. return (enemies.any? {|e| e.states.include?(s_id)})
  3316. end
  3317. #--------------------------------------------------------------------------
  3318. # enemy_can_see?
  3319. # id - event ID
  3320. # target_type - enemies or actors
  3321. # target - which target
  3322. # Checks is the given enemy can see a specific battler.
  3323. #--------------------------------------------------------------------------
  3324. def enemy_can_see?(id, target_type, target)
  3325. # get enemies
  3326. enemies = get_enemies(id)
  3327. # can't see if not a battler
  3328. return false unless enemies[0].is_a?(Map_Battler)
  3329. # get targets to check
  3330. targets = get_targets(target_type, target)
  3331. # return result
  3332. return (enemies.any? {|e| (targets & e.ai.sight).size > 0})
  3333. end
  3334. #--------------------------------------------------------------------------
  3335. # enemy_can_hear?
  3336. # id - event ID
  3337. # target_type - enemies or actors
  3338. # target - which target
  3339. # Checks is the given enemy can see a specific battler.
  3340. #--------------------------------------------------------------------------
  3341. def enemy_can_hear?(id, target_type, target)
  3342. # get enemies
  3343. enemies = get_enemies(id)
  3344. # can't see if not a battler
  3345. return false unless enemies[0].is_a?(Map_Battler)
  3346. # get targets to check
  3347. targets = get_targets(target_type, target)
  3348. # return result
  3349. return (targets.any? {|t| enemies.any? {|e|
  3350. $BlizzABS.AI.can_hear_char?(e, t.real_x, t.real_y)}})
  3351. end
  3352. #--------------------------------------------------------------------------
  3353. # enemy_can_perceive?
  3354. # id - event ID
  3355. # target_type - enemies or actors
  3356. # target - which target
  3357. # Checks is the given enemy can see a specific battler.
  3358. #--------------------------------------------------------------------------
  3359. def enemy_can_perceive?(id, target_type, target)
  3360. # get enemies
  3361. enemies = get_enemies(id)
  3362. # can't see if not a battler
  3363. return false unless enemies[0].is_a?(Map_Battler)
  3364. # get targets to check
  3365. targets = get_targets(target_type, target)
  3366. # return result
  3367. return (targets.any? {|t| enemies.any? {|e|
  3368. $BlizzABS.AI.can_perceive_char?(e, t.real_x, t.real_y)}})
  3369. end
  3370. #--------------------------------------------------------------------------
  3371. # enemy_has_memorized?
  3372. # id - event ID
  3373. # target_type - enemies or actors
  3374. # target - which target
  3375. # Checks is the given enemy can see a specific battler.
  3376. #--------------------------------------------------------------------------
  3377. def enemy_has_memorized?(id, target_type, target)
  3378. # get enemies
  3379. enemies = get_enemies(id)
  3380. # can't see if not a battler
  3381. return false unless enemies[0].is_a?(Map_Battler)
  3382. # get targets to check
  3383. targets = get_targets(target_type, target)
  3384. # return result
  3385. return (enemies.any? {|e| targets.size > 0 || e.ai.memory.keys.size > 0})
  3386. end
  3387. #--------------------------------------------------------------------------
  3388. # create_event
  3389. # x - x-coordinate
  3390. # y - y-coordinate
  3391. # name - event name
  3392. # page_data - contains data for each page
  3393. # Creates an event on the map.
  3394. #--------------------------------------------------------------------------
  3395. def create_event(x, y, name, page_data)
  3396. # create event
  3397. event = RPG::Event.new(x, y)
  3398. # get keys
  3399. keys = $game_map.events.keys
  3400. # set new ID
  3401. event.id = (keys.size == 0 ? 1 : keys.max + 1)
  3402. # set own event name DROP + ID
  3403. event.name = name
  3404. if page_data.size > 0
  3405. # clear page data
  3406. event.pages.clear
  3407. # set page data
  3408. page_data.each {|p| event.pages.push(create_event_page(p))}
  3409. end
  3410. # add to map
  3411. $game_map.map.events[event.id] = event
  3412. $game_map.events[event.id] = Game_Event.new($game_map.map_id, event)
  3413. # update name
  3414. check_event_name(event.id)
  3415. # create spriteset
  3416. sprite = Sprite_Character.new($scene.spriteset.viewport1, $game_map.events[event.id])
  3417. # add to spriteset handler
  3418. $scene.spriteset.character_sprites.push(sprite)
  3419. # refresh map
  3420. $game_map.need_refresh = true
  3421. # return event id
  3422. return event.id
  3423. end
  3424. #--------------------------------------------------------------------------
  3425. # create_event_page
  3426. # data - event page data
  3427. # Creates an event page.
  3428. #--------------------------------------------------------------------------
  3429. def create_event_page(data)
  3430. # create new page
  3431. page = RPG::Event::Page.new
  3432. # return if empty page
  3433. return page if data.size == 0
  3434. # set page data
  3435. page.condition = create_event_page_condition(data[0])
  3436. page.graphic = create_event_page_graphic(data[1])
  3437. page.move_type = data[2]
  3438. page.move_speed = data[3]
  3439. page.move_frequency = data[4]
  3440. page.move_route = create_move_route(data[5])
  3441. page.walk_anime = data[6]
  3442. page.step_anime = data[7]
  3443. page.direction_fix = data[8]
  3444. page.through = data[9]
  3445. page.always_on_top = data[10]
  3446. page.trigger = data[11]
  3447. if data[12].size > 0
  3448. page.list = []
  3449. data[12].each {|d| page.list.push(create_event_command(d))}
  3450. end
  3451. # return completed page
  3452. return page
  3453. end
  3454. #--------------------------------------------------------------------------
  3455. # create_event_page_condition
  3456. # data - event page condition data
  3457. # Creates an event page condition.
  3458. #--------------------------------------------------------------------------
  3459. def create_event_page_condition(data)
  3460. # create new condition
  3461. condition = RPG::Event::Page::Condition.new
  3462. # return if empty condition
  3463. return condition if data.size == 0
  3464. # set condition data
  3465. condition.switch1_valid = data[0]
  3466. condition.switch2_valid = data[1]
  3467. condition.variable_valid = data[2]
  3468. condition.self_switch_valid = data[3]
  3469. condition.switch1_id = data[4]
  3470. condition.switch2_id = data[5]
  3471. condition.variable_id = data[6]
  3472. condition.variable_value = data[7]
  3473. condition.self_switch_ch = data[8]
  3474. # return completed condition
  3475. return condition
  3476. end
  3477. #--------------------------------------------------------------------------
  3478. # create_event_page_graphic
  3479. # data - event page graphic data
  3480. # Creates an event page graphic.
  3481. #--------------------------------------------------------------------------
  3482. def create_event_page_graphic(data)
  3483. # create new graphic
  3484. graphic = RPG::Event::Page::Graphic.new
  3485. # return if empty graphic
  3486. return graphic if data.size == 0
  3487. # set graphic data
  3488. graphic.tile_id = data[0]
  3489. graphic.character_name = data[1]
  3490. graphic.character_hue = data[2]
  3491. graphic.direction = data[3]
  3492. graphic.pattern = data[4]
  3493. graphic.opacity = data[5]
  3494. graphic.blend_type = data[6]
  3495. # return completed graphic
  3496. return graphic
  3497. end
  3498. #--------------------------------------------------------------------------
  3499. # create_move_route
  3500. # data - move route data
  3501. # Creates a move route.
  3502. #--------------------------------------------------------------------------
  3503. def create_move_route(data)
  3504. # create new move route
  3505. move_route = RPG::MoveRoute.new
  3506. # return if empty move route
  3507. return move_route if data.size == 0
  3508. # set move route data
  3509. move_route.repeat = data[0]
  3510. move_route.skippable = data[1]
  3511. if move_route.list.size > 0
  3512. move_route.list = []
  3513. data[2].each {|d| move_route.list.push(create_move_command(d))}
  3514. end
  3515. # return completed move route
  3516. return move_route
  3517. end
  3518. #--------------------------------------------------------------------------
  3519. # create_move_command
  3520. # data - move command data
  3521. # Creates a move command.
  3522. #--------------------------------------------------------------------------
  3523. def create_move_command(data)
  3524. # create new command
  3525. command = RPG::MoveCommand.new
  3526. # return if empty command
  3527. return command if data.size == 0
  3528. # set command data
  3529. command.code = data[0]
  3530. command.parameters = data[1]
  3531. # return completed command
  3532. return command
  3533. end
  3534. #--------------------------------------------------------------------------
  3535. # create_event_command
  3536. # data - event command data
  3537. # Creates an event command.
  3538. #--------------------------------------------------------------------------
  3539. def create_event_command(data)
  3540. # create new command
  3541. command = RPG::EventCommand.new
  3542. # return if empty command
  3543. return command if data.size == 0
  3544. # set command data
  3545. command.code = data[0]
  3546. command.indent = data[1]
  3547. command.parameters = data[2]
  3548. # return completed command
  3549. return command
  3550. end
  3551. end
  3552.  
  3553. end
  3554.  
  3555. module BlizzABS
  3556.  
  3557. #============================================================================
  3558. # BlizzABS::Controller
  3559. #----------------------------------------------------------------------------
  3560. # This class is a special controller that controls the party leader. Some
  3561. # input is processed instantly, while some is converted into commands to be
  3562. # given to the player character.
  3563. #============================================================================
  3564.  
  3565. class Controller
  3566.  
  3567. # Center screen x-coordinate * 4
  3568. CX = (320 - 16) * 4
  3569. # Center screen y-coordinate * 4
  3570. CY = (240 - 16) * 4
  3571.  
  3572. # set all accessible variables
  3573. attr_accessor :encounter_count
  3574. #--------------------------------------------------------------------------
  3575. # Initialization
  3576. #--------------------------------------------------------------------------
  3577. def initialize
  3578. # set memory jump
  3579. @memory_jump = false
  3580. end
  3581. #--------------------------------------------------------------------------
  3582. # player
  3583. # Makes the code easier to read.
  3584. #--------------------------------------------------------------------------
  3585. def player
  3586. return $BlizzABS.actors[0]
  3587. end
  3588. #--------------------------------------------------------------------------
  3589. # update_control
  3590. # Processes player control.
  3591. #--------------------------------------------------------------------------
  3592. def update_control
  3593. # get pixel movement rate
  3594. pix = $BlizzABS.pixel
  3595. # reset move speed
  3596. player.move_speed = player.normal_speed
  3597. # reset spriteset name
  3598. player.character_name = player.character_name_org
  3599. # if allowed to change speed
  3600. unless $game_system.map_interpreter.running? ||
  3601. player.move_route_forcing || $game_temp.message_window_showing
  3602. # if run button works and running
  3603. if $game_system.running_button && Input.press?(Input::Run)
  3604. # set running speed
  3605. player.move_speed = Config::RUN_SPEED
  3606. # if sneak button works and sneaking
  3607. elsif $game_system.sneaking_button && Input.press?(Input::Sneak) ||
  3608. Config::SNEAK_SPEED > 0 && Config::SNEAK_ON_CHARGE && player.charging?
  3609. # set sneaking speed
  3610. player.move_speed = Config::SNEAK_SPEED
  3611. end
  3612. end
  3613. # if battler exists and either dead or select triggered
  3614. if player.battler != nil && ($game_system.select_button &&
  3615. Input.trigger?(Input::Select) || player.battler.dead?)
  3616. # switch to next valid actor
  3617. switch_leader
  3618. end
  3619. # setup sprite animation
  3620. player.sprite_animation_setup
  3621. # update action
  3622. player.update_action
  3623. # if allowed to turn and pressed turning button or defending
  3624. if ((player.ai.act.defend? && player.attacked == 0) ||
  3625. $game_system.turn_button && Input.press?(Input::Turn)) &&
  3626. !player.moving? && !$game_system.map_interpreter.running? &&
  3627. !player.move_route_forcing && !$game_temp.message_window_showing
  3628. # get input depending on confusion
  3629. input = (player.restriction == 3 ? 10 - Input.dir4 : Input.dir4)
  3630. # depending on input turn
  3631. case input
  3632. when 2 then player.turn_down
  3633. when 4 then player.turn_left
  3634. when 6 then player.turn_right
  3635. when 8 then player.turn_up
  3636. end
  3637. # updates any attacked action
  3638. player.update_attacked
  3639. # abort method
  3640. return nil
  3641. end
  3642. # updates any attacked action
  3643. player.update_attacked
  3644. # if acting
  3645. if player.in_action > 0
  3646. # decrease action counter if in_action is greater than 0
  3647. player.in_action -= 1 if player.in_action > 0
  3648. # return data
  3649. return [player.moving?, player.real_x, player.real_y]
  3650. end
  3651. # if allowed to move
  3652. unless $game_system.map_interpreter.running? ||
  3653. player.move_route_forcing || $game_temp.message_window_showing
  3654. # if jump button was pressed and not already jumping
  3655. if $game_system.jumping_button && Input.trigger?(Input::Jump) &&
  3656. !player.jumping? && player.restriction < 4
  3657. # set to jump
  3658. @memory_jump = true
  3659. end
  3660. # if not moving
  3661. unless player.moving?
  3662. # get jumping range
  3663. range = Config::JUMPING
  3664. # if jumping turned on and not jumping and jumped
  3665. if range > 0 && !player.jumping? && @memory_jump
  3666. # if sneaking or running is possible
  3667. if Config::RUN_SPEED > 0 || Config::SNEAK_SPEED > 0
  3668. # get difference between current speed and normal speed
  3669. dplus = player.move_speed - player.normal_speed
  3670. else
  3671. # difference is 0
  3672. dplus = 0
  3673. end
  3674. # get direction
  3675. direction = $game_system._8_way ? Input.dir8 : Input.dir4
  3676. # set jumping direction
  3677. x, y = Cache::DirOffsets[direction]
  3678. # jump into direction with considering running/sneaking
  3679. player.jump(x*range + x*dplus, y*range + y*dplus, direction)
  3680. # if not already jumping
  3681. elsif !player.jumping?
  3682. # move
  3683. move($game_system._8_way ? Input.dir8 : Input.dir4)
  3684. # allow idle if no movement
  3685. player.idle_allowed = !player.moving?
  3686. end
  3687. # not jumping anymore
  3688. @memory_jump = false
  3689. end
  3690. end
  3691. # return data
  3692. return [player.moving?, player.real_x, player.real_y]
  3693. end
  3694. #--------------------------------------------------------------------------
  3695. # switch_leader
  3696. # Switches to the next valid actor as leader.
  3697. #--------------------------------------------------------------------------
  3698. def switch_leader
  3699. # store the old party leader
  3700. leader = player
  3701. # iterate "number of party members" times
  3702. $game_party.actors.size.times {
  3703. # change party leader
  3704. $game_party.add_actor($game_party.actors.shift.id)
  3705. # until finding one who's not dead
  3706. break if $game_party.actors[0] != nil && !$game_party.actors[0].dead?}
  3707. # stop if party leader has not changed
  3708. return if leader == player
  3709. # enforce emptying moving buffer and add special command
  3710. update_buffer(nil)
  3711. # center screen display on new player controlled character
  3712. center(player.x, player.y, true) if $game_system.caterpillar
  3713. # except if charging
  3714. unless player.charging?
  3715. # reset player action
  3716. player.reset_action
  3717. # reset player action counter
  3718. player.in_action = 0
  3719. end
  3720. # except if charging
  3721. unless leader.charging?
  3722. # reset old leader action
  3723. leader.reset_action
  3724. # reset old leader action counter
  3725. leader.in_action = 0
  3726. end
  3727. # set flag for HUD update
  3728. $game_temp.hud_refresh = true
  3729. end
  3730. #--------------------------------------------------------------------------
  3731. # move
  3732. # dir - direction
  3733. # Make the code easier to read. It moves the player in the appropriate
  3734. # direction then.
  3735. #--------------------------------------------------------------------------
  3736. def move(dir)
  3737. return case (player.restriction == 3 ? 10 - dir : dir)
  3738. when 1 then player.move_lower_left
  3739. when 2 then player.move_down
  3740. when 3 then player.move_lower_right
  3741. when 4 then player.move_left
  3742. when 6 then player.move_right
  3743. when 7 then player.move_upper_left
  3744. when 8 then player.move_up
  3745. when 9 then player.move_upper_right
  3746. end
  3747. end
  3748. #--------------------------------------------------------------------------
  3749. # update_moving
  3750. # Processes player control.
  3751. #--------------------------------------------------------------------------
  3752. def update_moving(data)
  3753. # if control update was not aborted
  3754. if data != nil
  3755. # get data
  3756. moved, x, y = data
  3757. # if moved down
  3758. if player.real_y > y && player.real_y - $game_map.display_y > CY
  3759. # scroll screen down
  3760. $game_map.scroll_down(player.real_y - y)
  3761. end
  3762. # if moved left
  3763. if player.real_x < x && player.real_x - $game_map.display_x < CX
  3764. # scroll screen left
  3765. $game_map.scroll_left(x - player.real_x)
  3766. end
  3767. # if moved right
  3768. if player.real_x > x && player.real_x - $game_map.display_x > CX
  3769. # scroll screen right
  3770. $game_map.scroll_right(player.real_x - x)
  3771. end
  3772. # if moved up
  3773. if player.real_y < y && player.real_y - $game_map.display_y < CY
  3774. # scroll screen up
  3775. $game_map.scroll_up(y - player.real_y)
  3776. end
  3777. # if not moving
  3778. unless player.moving?
  3779. # if last moving, not activated, not override and countdown
  3780. if moved && !check_event_trigger_here(Cache::TouchTrigger) &&
  3781. !($DEBUG && Input.press?(Input::CTRL)) && @encounter_count > 0
  3782. # set battle-encounter countdown
  3783. @encounter_count -= 2 ** (5 - $game_system.pixel_rate)
  3784. @encounter_count = 0 if @encounter_count < 0
  3785. end
  3786. # if pressed C button
  3787. if Input.trigger?(Input::C)
  3788. # check event here
  3789. check_event_trigger_here(Cache::PressTrigger)
  3790. # check event there
  3791. check_event_trigger_there(Cache::BasicTrigger)
  3792. end
  3793. end
  3794. end
  3795. # update each other actor except the player
  3796. ($BlizzABS.battlers - [player]).each {|actor| actor.update}
  3797. end
  3798. #--------------------------------------------------------------------------
  3799. # update_buffer
  3800. # move - new command
  3801. # Updates the buffer of the last moving commands.
  3802. #--------------------------------------------------------------------------
  3803. def update_buffer(move)
  3804. # if new command requires so
  3805. if move == nil || move == false
  3806. # empty each actor's buffer
  3807. $BlizzABS.battlers.each {|actor| actor.force_move = []}
  3808. end
  3809. # add new command or enforce emptying whether move is reset for each actor
  3810. $BlizzABS.battlers.each {|actor| actor.update_buffer(move == 'reset' ? nil : move)}
  3811. end
  3812. #--------------------------------------------------------------------------
  3813. # refresh
  3814. # Refreshes the character.
  3815. #--------------------------------------------------------------------------
  3816. def refresh
  3817. # test on changes in the inner structure of $game_party.actors
  3818. if $BlizzABS.actors.any? {|actor|
  3819. actor.battler(true) == nil && $game_party.actors[actor.index] != nil ||
  3820. actor.battler(true) != $game_party.actors[actor.index]}
  3821. # if caterpillar is on
  3822. if $game_system.caterpillar
  3823. # store old array, create 2 new arrays
  3824. old, tmp, $BlizzABS.actors = $BlizzABS.actors, [], []
  3825. # for each old actor
  3826. old.each {|a|
  3827. # if battler exists and in party
  3828. if a.battler(true) != nil && a.battler(true).index != nil &&
  3829. a.battler(true).index < BlizzABS::Config::MAX_PARTY
  3830. # add actor on position
  3831. $BlizzABS.actors[a.battler(true).index] = a
  3832. end}
  3833. # for the rest of the old actors
  3834. (old - $BlizzABS.actors).each {|a|
  3835. # if not in party
  3836. if a.battler(true) != nil && (a.battler(true).index == nil ||
  3837. a.battler(true).index >= BlizzABS::Config::MAX_PARTY)
  3838. # remove battler
  3839. a.battler = nil
  3840. end
  3841. # add actor
  3842. tmp.push(a)}
  3843. # fill the empty places between
  3844. $BlizzABS.actors.each_index {|i|
  3845. $BlizzABS.actors[i] = tmp.shift if $BlizzABS.actors[i] == nil}
  3846. # add rest of actors
  3847. $BlizzABS.actors += tmp
  3848. # for each actor
  3849. $BlizzABS.actors.each {|a|
  3850. # if no battler assigned, but in the party is a battler
  3851. if a.battler(true) == nil && $game_party.actors[a.index] != nil
  3852. # assign battler
  3853. a.battler = $game_party.actors[a.index]
  3854. end}
  3855. else
  3856. # set the correct battlers
  3857. $BlizzABS.actors.each_index {|i|
  3858. $BlizzABS.actors[i].battler = $game_party.actors[i]}
  3859. end
  3860. end
  3861. # each actor
  3862. $BlizzABS.battlers.each {|actor|
  3863. # refresh spriteset
  3864. actor.refresh(true)
  3865. # set to return to caterpillar for convenience
  3866. actor.ai.state = AI::Return
  3867. # if actor not valid
  3868. unless actor.valid?
  3869. # reset action
  3870. actor.ai.target = nil
  3871. actor.ai.act.set
  3872. end}
  3873. # set new $game_player character
  3874. $game_player = player
  3875. end
  3876. #--------------------------------------------------------------------------
  3877. # moveto
  3878. # x - x-coordinate
  3879. # y - y-coordinate
  3880. # Moves the player instantly to a position, moves all actors and centers
  3881. # the screen upon the player.
  3882. #--------------------------------------------------------------------------
  3883. def moveto(x, y)
  3884. # center screen upon player
  3885. center(x, y)
  3886. # for each actor
  3887. ($BlizzABS.battlers - [player]).each {|actor|
  3888. # return to caterpillar if not in caterpillar
  3889. actor.return_to_caterpillar if actor.cindex == nil}
  3890. # empty movement command buffer
  3891. update_buffer(nil)
  3892. # move each actor to the same position
  3893. ($BlizzABS.battlers - [player]).each {|actor| actor.moveto(x, y)}
  3894. # create battle-encounter countdown
  3895. player.make_encounter_count
  3896. end
  3897. #--------------------------------------------------------------------------
  3898. # center
  3899. # x - x-coordinate
  3900. # y - y-coordinate
  3901. # Centers the screen upon the player. (pixel movement)
  3902. #--------------------------------------------------------------------------
  3903. def center(x, y, flag = false)
  3904. # set pix value
  3905. pix = flag ? $BlizzABS.pixel : 1
  3906. # resize coordinates
  3907. x, y = x * 128 / pix, y * 128 / pix
  3908. # get maximum coordinates of map
  3909. m_x, m_y = ($game_map.width - 20) * 128, ($game_map.height - 15) * 128
  3910. ox, oy = x - CX, y - CY
  3911. # set new display coordinates
  3912. if ox > m_x
  3913. $game_map.display_x = m_x
  3914. elsif ox < 0
  3915. $game_map.display_x = 0
  3916. else
  3917. $game_map.display_x = ox
  3918. end
  3919. if oy > m_y
  3920. $game_map.display_y = m_y
  3921. elsif oy < 0
  3922. $game_map.display_y = 0
  3923. else
  3924. $game_map.display_y = oy
  3925. end
  3926. end
  3927. #--------------------------------------------------------------------------
  3928. # check_event_trigger_here
  3929. # triggers - possible event triggers
  3930. # Checks if there are events to be triggered. (pixel movement)
  3931. #--------------------------------------------------------------------------
  3932. def check_event_trigger_here(triggers)
  3933. # not started if already running
  3934. return false if $game_system.map_interpreter.running?
  3935. # get pixel movement rate
  3936. pix = $BlizzABS.pixel
  3937. # initialize result
  3938. result = false
  3939. # iterate through all events
  3940. $game_map.events.each_value {|event|
  3941. # if coordinates fit and can be triggered and not jumping
  3942. if event.x == (player.x+pix/2)/pix &&
  3943. event.y == (player.y+pix/2)/pix &&
  3944. triggers.include?(event.trigger) && !event.jumping? &&
  3945. event.over_trigger?
  3946. # start event
  3947. event.start
  3948. # events were started
  3949. result = true
  3950. end}
  3951. # return result
  3952. return result
  3953. end
  3954. #--------------------------------------------------------------------------
  3955. # check_event_trigger_there
  3956. # triggers - possible event triggers
  3957. # Checks if there are events to be triggered. (pixel movement)
  3958. #--------------------------------------------------------------------------
  3959. def check_event_trigger_there(triggers)
  3960. # not started if already running
  3961. return false if $game_system.map_interpreter.running?
  3962. # get pixel movement rate
  3963. pix = $BlizzABS.pixel
  3964. # calculate new coordinates
  3965. nx = player.x + (player.direction == 6 ? 1 : player.direction == 4 ? -1 : 0)*pix
  3966. ny = player.y + (player.direction == 2 ? 1 : player.direction == 8 ? -1 : 0)*pix
  3967. # initialize result
  3968. result = false
  3969. # iterate through all events
  3970. $game_map.events.each_value {|event|
  3971. # if triggered by touch and trigger started the event
  3972. if triggers.include?(event.trigger) &&
  3973. event.check_event_trigger_at(nx, ny)
  3974. # events were started
  3975. result = true
  3976. end}
  3977. # if event was not started and counter
  3978. if !result && $game_map.pixel_counter?(nx, ny)
  3979. # change new coordinates
  3980. nx += (player.direction == 6 ? 1 : player.direction == 4 ? -1 : 0)*pix
  3981. ny += (player.direction == 2 ? 1 : player.direction == 8 ? -1 : 0)*pix
  3982. # iterate through all events
  3983. $game_map.events.each_value {|event|
  3984. # if triggered by touch and trigger started the event
  3985. if triggers.include?(event.trigger) &&
  3986. event.check_event_trigger_at(nx, ny)
  3987. # events were started
  3988. result = true
  3989. end}
  3990. end
  3991. # return result
  3992. return result
  3993. end
  3994. #--------------------------------------------------------------------------
  3995. # check_event_trigger_touch
  3996. # x - x-coordinate
  3997. # y - y-coordinate
  3998. # Checks if there are events that were triggered by touch. (pixel movement)
  3999. #--------------------------------------------------------------------------
  4000. def check_event_trigger_touch(x, y)
  4001. # not started if already running
  4002. return false if $game_system.map_interpreter.running?
  4003. # get pixel movement rate
  4004. pix = $BlizzABS.pixel
  4005. # initialize result
  4006. result = false
  4007. # iterate through all events
  4008. $game_map.events.each_value {|event|
  4009. # if triggered by touch and trigger started the event
  4010. if Cache::TouchTrigger.include?(event.trigger) &&
  4011. event.check_event_trigger_at(x, y)
  4012. # events were started
  4013. result = true
  4014. end}
  4015. # return result
  4016. return result
  4017. end
  4018. #--------------------------------------------------------------------------
  4019. # cancel_path_request?
  4020. # Decides if player is trying to cancel path request.
  4021. #--------------------------------------------------------------------------
  4022. def cancel_path_request?
  4023. # true if directional input, turn, jump, or battle action
  4024. return Input.dir4 != 0 ||
  4025. ($game_system.select_button && Input.press?(Input::Select)) ||
  4026. ($game_system.turn_button && Input.press?(Input::Turn)) ||
  4027. ($game_system.jumping_button && Input.press?(Input::Jump)) ||
  4028. ($game_system.attack_button && Input.press?(Input::Attack) ||
  4029. ($game_system.defend_button && Input.press?(Input::Defend)) ||
  4030. ($game_system.skill_button && Input.press?(Input::Skill)) ||
  4031. ($game_system.item_button && Input.press?(Input::Item)))
  4032. end
  4033. end
  4034.  
  4035. end
  4036.  
  4037. module BlizzABS
  4038.  
  4039. #============================================================================
  4040. # BlizzABS::Trigger
  4041. #----------------------------------------------------------------------------
  4042. # This class provides a data interface for AI Trigger data packs.
  4043. #============================================================================
  4044.  
  4045. class Trigger
  4046.  
  4047. # setting all accessible variables
  4048. attr_accessor :activator
  4049. attr_accessor :condition
  4050. attr_accessor :comparator
  4051. attr_accessor :value
  4052. attr_accessor :action_type
  4053. attr_accessor :action_data
  4054. attr_accessor :target
  4055. #--------------------------------------------------------------------------
  4056. # Initialization
  4057. # activator - the battler type that activates the trigger
  4058. # condition - conditional operand A
  4059. # comparator - comparison operator
  4060. # value - conditional operand B
  4061. # action_type - action type
  4062. # action_data - data supporting the action type
  4063. # target - target type
  4064. #--------------------------------------------------------------------------
  4065. def initialize(activator = TRGLeader, condition = TRGHP,
  4066. comparator = TRGEqual, value = 100, action_type = TRGAttack,
  4067. action_data = 0, target = TRGTargetDefault)
  4068. @activator = activator
  4069. @condition = condition
  4070. @comparator = comparator
  4071. @value = value
  4072. @action_type = action_type
  4073. @action_data = action_data
  4074. @target = target
  4075. end
  4076. #--------------------------------------------------------------------------
  4077. # battler_activator?
  4078. # Checks if the trigger is activated by a battler type.
  4079. #--------------------------------------------------------------------------
  4080. def battler_activator?
  4081. return (@activator != TRGProbability)
  4082. end
  4083. #--------------------------------------------------------------------------
  4084. # get_a_target
  4085. # char - the hosting actor
  4086. # targets - possible targets
  4087. # Checks the condition of the trigger with the given targets and returns
  4088. # the chosen target.
  4089. #--------------------------------------------------------------------------
  4090. def get_a_target(char, targets)
  4091. # check trigger condition
  4092. case @condition
  4093. when TRGHP # HP condition
  4094. # for each possible target
  4095. targets.each {|b|
  4096. # get comparator string
  4097. comparator = Cache::TRGComparators[@comparator]
  4098. # evaluate condition
  4099. if eval("b.battler.hp * 100 / b.battler.maxhp #{comparator} @value")
  4100. # this target fulfills the condition
  4101. return b
  4102. end}
  4103. when TRGSP # SP condition
  4104. # for each possible target
  4105. targets.each {|b|
  4106. # get comparator string
  4107. comparator = Cache::TRGComparators[@comparator]
  4108. # evaluate condition
  4109. if eval("b.battler.sp * 100 / b.battler.maxsp #{comparator} @value")
  4110. # this target fulfills the condition
  4111. return b
  4112. end}
  4113. when TRGState # State condition
  4114. # if no state condition
  4115. if @value == 0
  4116. # find a target that has no states
  4117. targets.each {|b| return b if b.battler.states.size == 0}
  4118. else
  4119. # find a target with the condition state
  4120. targets.each {|b| return b if b.battler.states.include?(@value)}
  4121. end
  4122. when TRGLocation # Location condition
  4123. # temporary variable
  4124. pix = $BlizzABS.pixel
  4125. # sort all targets by relative distance ascending
  4126. targets.sort! {|a, b|
  4127. Math.hypot(char.x / pix - a.x / pix, char.y / pix - a.y / pix) <=>
  4128. Math.hypot(char.x / pix - b.x / pix, char.y / pix - b.y / pix)}
  4129. # return the requested battler
  4130. return case @value
  4131. when TRGClosest then targets[0]
  4132. when TRGFarthest then targets[targets.size - 1]
  4133. end
  4134. end
  4135. # this trigger has not been activated
  4136. return nil
  4137. end
  4138.  
  4139. end
  4140.  
  4141. #============================================================================
  4142. # BlizzABS::Action
  4143. #----------------------------------------------------------------------------
  4144. # This class provides a data interface for action data packs.
  4145. #============================================================================
  4146.  
  4147. class Action
  4148.  
  4149. # setting all accessible variables
  4150. attr_accessor :range
  4151. attr_accessor :kind
  4152. attr_accessor :id
  4153. attr_accessor :type
  4154. attr_accessor :delay
  4155. attr_accessor :forced
  4156. #--------------------------------------------------------------------------
  4157. # Initialization
  4158. # range - range of the action
  4159. # kind - action kind
  4160. # id - action id
  4161. # type - action type
  4162. # delay - delay time
  4163. # forced - forced action
  4164. #--------------------------------------------------------------------------
  4165. def initialize(range = 0, kind = 0, id = 0, type = 0, delay = 0,
  4166. forced = false)
  4167. set(range, kind, id, type, delay, forced)
  4168. end
  4169. #--------------------------------------------------------------------------
  4170. # set
  4171. # range - range of the action
  4172. # kind - action kind
  4173. # id - action id
  4174. # type - action type
  4175. # delay - delay time
  4176. # forced - forced action
  4177. # Sets all action's parameters at once.
  4178. #--------------------------------------------------------------------------
  4179. def set(range = 0, kind = 0, id = 0, type = 0, delay = 0, forced = false)
  4180. @range = range
  4181. @kind = kind
  4182. @id = id
  4183. @type = type
  4184. @delay = delay
  4185. @forced = forced
  4186. end
  4187. #--------------------------------------------------------------------------
  4188. # valid?
  4189. # Checks if the action is actually an action.
  4190. #--------------------------------------------------------------------------
  4191. def valid?
  4192. return (@kind != ACTNone)
  4193. end
  4194. #--------------------------------------------------------------------------
  4195. # basic?
  4196. # Checks if the action is a basic action.
  4197. #--------------------------------------------------------------------------
  4198. def basic?
  4199. return (attack? || defend? || escape?)
  4200. end
  4201. #--------------------------------------------------------------------------
  4202. # attack?
  4203. # Checks if the action is an attack.
  4204. #--------------------------------------------------------------------------
  4205. def attack?
  4206. return (@kind == ACTAttack)
  4207. end
  4208. #--------------------------------------------------------------------------
  4209. # defend?
  4210. # Checks if the action is a defending action.
  4211. #--------------------------------------------------------------------------
  4212. def defend?
  4213. return (@kind == ACTDefend)
  4214. end
  4215. #--------------------------------------------------------------------------
  4216. # escape?
  4217. # Checks if the action is an escaping action.
  4218. #--------------------------------------------------------------------------
  4219. def escape?
  4220. return (@kind == ACTEscape)
  4221. end
  4222. #--------------------------------------------------------------------------
  4223. # skill?
  4224. # Checks if the action is a skill.
  4225. #--------------------------------------------------------------------------
  4226. def skill?
  4227. return (@kind == ACTSkill)
  4228. end
  4229. #--------------------------------------------------------------------------
  4230. # item?
  4231. # Checks if the action is an item use.
  4232. #--------------------------------------------------------------------------
  4233. def item?
  4234. return (@kind == ACTItem)
  4235. end
  4236. #--------------------------------------------------------------------------
  4237. # ready?
  4238. # Checks if the action is ready to be executed.
  4239. #--------------------------------------------------------------------------
  4240. def ready?
  4241. return (@delay <= 0)
  4242. end
  4243.  
  4244. end
  4245.  
  4246. #============================================================================
  4247. # BlizzABS::ChargeData
  4248. #----------------------------------------------------------------------------
  4249. # This class provides a data interface for action charges.
  4250. #============================================================================
  4251.  
  4252. class ChargeData
  4253.  
  4254. # setting all accessible variables
  4255. attr_accessor :type
  4256. attr_accessor :time
  4257. attr_accessor :action
  4258. attr_accessor :id
  4259. #--------------------------------------------------------------------------
  4260. # Initialization
  4261. # type - charge type
  4262. # time - time to charge up
  4263. # action - action type
  4264. # id - action ID
  4265. #--------------------------------------------------------------------------
  4266. def initialize(type, time, action, id)
  4267. @type, @time, @action, @id = type, time, action, id
  4268. end
  4269. #--------------------------------------------------------------------------
  4270. # charged?
  4271. # Checks if the action has been charged.
  4272. #--------------------------------------------------------------------------
  4273. def charged?
  4274. return (@time <= 0)
  4275. end
  4276.  
  4277. end
  4278.  
  4279. #============================================================================
  4280. # BlizzABS::MemoryData
  4281. #----------------------------------------------------------------------------
  4282. # This class provides a data interface for enemy memory data about other
  4283. # battlers one the map.
  4284. #============================================================================
  4285.  
  4286. class MemoryData
  4287.  
  4288. # setting all accessible variables
  4289. attr_accessor :x
  4290. attr_accessor :y
  4291. #--------------------------------------------------------------------------
  4292. # Initialization
  4293. # x - x-coordinate of memorized battler
  4294. # y - y-coordinate of memorized battler
  4295. #--------------------------------------------------------------------------
  4296. def initialize(x, y)
  4297. @x, @y = x, y
  4298. end
  4299.  
  4300. end
  4301.  
  4302. #============================================================================
  4303. # BlizzABS::ObserveData
  4304. #----------------------------------------------------------------------------
  4305. # This class provides a data interface for observation logs.
  4306. #============================================================================
  4307.  
  4308. class ObserveData
  4309.  
  4310. # setting all accessible variables
  4311. attr_accessor :damage
  4312. attr_accessor :time
  4313. #--------------------------------------------------------------------------
  4314. # Initialization
  4315. # damage - the damage value
  4316. # time - the moment in time when the damage was done
  4317. #--------------------------------------------------------------------------
  4318. def initialize(damage, time)
  4319. @damage, @time = damage, time
  4320. end
  4321.  
  4322. end
  4323.  
  4324. #============================================================================
  4325. # BlizzABS::DamageRequest
  4326. #----------------------------------------------------------------------------
  4327. # This class provides a data interface for damage sprite requests.
  4328. #============================================================================
  4329.  
  4330. class DamageRequest
  4331.  
  4332. # setting all accessible variables
  4333. attr_reader :x
  4334. attr_reader :y
  4335. attr_reader :damage
  4336. attr_reader :critical
  4337. attr_reader :color
  4338. attr_reader :width
  4339. attr_reader :height
  4340. #--------------------------------------------------------------------------
  4341. # Initialization
  4342. # char - reference character for position
  4343. # damage - the damage value
  4344. # color - damage text color
  4345. # critical - critical flag
  4346. #--------------------------------------------------------------------------
  4347. def initialize(char, damage, color, critical = false)
  4348. # set coordinates
  4349. @x, @y = char.real_x / 4 + 16, char.real_y / 4 + 16
  4350. # set damage text value
  4351. @damage = (damage.is_a?(Numeric) ? damage.abs.to_s : damage.to_s)
  4352. # set color and critical flag
  4353. @color, @critical = color, critical
  4354. # create dummy bitmap
  4355. bitmap = Bitmap.new(1, 1)
  4356. # set font
  4357. bitmap.font.name = Cache::FontNameDamage
  4358. # set font size
  4359. bitmap.font.size = Cache::FontSizeDamage
  4360. # get size rectangle
  4361. size_rect = bitmap.text_size(@damage)
  4362. # get text width and height
  4363. @width, @height = (size_rect.width + 4) / 2 * 2, size_rect.height
  4364. @width = 1 if @width < 1
  4365. @height = 1 if @height < 1
  4366. end
  4367.  
  4368. end
  4369.  
  4370. #============================================================================
  4371. # BlizzABS::PathRequest
  4372. #----------------------------------------------------------------------------
  4373. # This class provides a data interface for path requests.
  4374. #============================================================================
  4375.  
  4376. class PathRequest
  4377.  
  4378. # setting all accessible variables
  4379. attr_reader :open
  4380. attr_reader :closed
  4381. attr_reader :sx
  4382. attr_reader :sy
  4383. attr_reader :tx
  4384. attr_reader :ty
  4385. attr_reader :jd
  4386. #--------------------------------------------------------------------------
  4387. # Initialization
  4388. # ox - real x-coordinate of starting point
  4389. # oy - real y-coordinate of starting point
  4390. # tx - x-coordinate of target point
  4391. # ty - y-coordinate of target point
  4392. # jd - jump distance (optional)
  4393. #--------------------------------------------------------------------------
  4394. def initialize(ox, oy, tx, ty, jd = 0)
  4395. # pixel movement rate
  4396. pix = $BlizzABS.pixel
  4397. # coordinates
  4398. @sx, @sy, @tx, @ty, @jd = ox / pix, oy / pix, tx / pix, ty / pix, jd / pix
  4399. # additional data
  4400. @x_off, @y_off = ox - @sx * pix, oy - @sy * pix
  4401. # nodes yet to check
  4402. @open = {[@sx, @sy] => -1}
  4403. # checked nodes
  4404. @closed = Table.new($game_map.width, $game_map.height)
  4405. end
  4406. #--------------------------------------------------------------------------
  4407. # backtrack
  4408. # Finds the way back from the target to the start to create a path.
  4409. #--------------------------------------------------------------------------
  4410. def backtrack
  4411. # get pixel movement rate
  4412. pix = $BlizzABS.pixel
  4413. # current x, y, target x, y and resulting path
  4414. cx, cy, x, y, result = @tx, @ty, 0, 0, []
  4415. # find the way back from destination to start
  4416. loop do
  4417. # change current coordinates
  4418. cx, cy = cx - x, cy - y
  4419. # stop if reached corrected start position
  4420. break if cx == @sx && cy == @sy
  4421. # add movement command
  4422. pix.times {result.unshift(Cache::TDirs[@closed[cx, cy]])}
  4423. # track back next node
  4424. x, y = Cache::DirOffsets[@closed[cx, cy]]
  4425. end
  4426. # modify found path if pixel movement is being used
  4427. modify(result) if pix > 1
  4428. # return result
  4429. return result
  4430. end
  4431. #--------------------------------------------------------------------------
  4432. # modify
  4433. # result - found path
  4434. # Modifies the path so it works with pixel movement
  4435. #--------------------------------------------------------------------------
  4436. def modify(result)
  4437. # add correction movement commands for x and y
  4438. @x_off.times {result.unshift(Cache::TDirs[4])}
  4439. @y_off.times {result.unshift(Cache::TDirs[8])}
  4440. # stop if not using 8 way movement
  4441. return if !$game_system._8_way
  4442. # add diagonal moving commands at positions where possible
  4443. result.each_index {|i|
  4444. # if both exist
  4445. if result[i] != nil && result[i + 1] != nil
  4446. # exchange of corner commands
  4447. case [result[i][0], result[i + 1][0]]
  4448. when Cache::DirDownLeft, Cache::DirLeftDown
  4449. result[i], result[i + 1] = Cache::TDirs[1], nil
  4450. when Cache::DirDownRight, Cache::DirRightDown
  4451. result[i], result[i + 1] = Cache::TDirs[3], nil
  4452. when Cache::DirLeftUp, Cache::DirUpLeft
  4453. result[i], result[i + 1] = Cache::TDirs[7], nil
  4454. when Cache::DirRightUp, Cache::DirUpRight
  4455. result[i], result[i + 1] = Cache::TDirs[9], nil
  4456. end
  4457. end}
  4458. # remove nils
  4459. result.compact!
  4460. end
  4461.  
  4462. end
  4463.  
  4464. #============================================================================
  4465. # BlizzABS::AlignmentData
  4466. #----------------------------------------------------------------------------
  4467. # This class provides a data interface for alignment groups.
  4468. #============================================================================
  4469.  
  4470. class AlignmentData
  4471.  
  4472. # setting all accessible variables
  4473. attr_accessor :id
  4474. attr_accessor :enemies
  4475. attr_accessor :allies
  4476. attr_accessor :neutral
  4477. #--------------------------------------------------------------------------
  4478. # Initialization
  4479. #--------------------------------------------------------------------------
  4480. def initialize(id)
  4481. @id = id
  4482. @enemies = BlizzABS::Alignments.enemies(id)
  4483. @allies = BlizzABS::Alignments.allies(id)
  4484. @neutral = BlizzABS::Alignments.neutral(id)
  4485. end
  4486. #--------------------------------------------------------------------------
  4487. # enemy?
  4488. # id - group ID
  4489. # Checks if a group is an enemy.
  4490. #--------------------------------------------------------------------------
  4491. def enemy?(id)
  4492. return @enemies.include?(id)
  4493. end
  4494. #--------------------------------------------------------------------------
  4495. # ally?
  4496. # id - group ID
  4497. # Checks if a group is an ally.
  4498. #--------------------------------------------------------------------------
  4499. def ally?(id)
  4500. return @allies.include?(id)
  4501. end
  4502. #--------------------------------------------------------------------------
  4503. # neutral?
  4504. # id - group ID
  4505. # Checks if a group is always neutral.
  4506. #--------------------------------------------------------------------------
  4507. def neutral?(id)
  4508. return @neutral.include?(id)
  4509. end
  4510.  
  4511. end
  4512.  
  4513. end
  4514.  
  4515. module BlizzABS
  4516.  
  4517. #============================================================================
  4518. # BlizzABS::Controls
  4519. #----------------------------------------------------------------------------
  4520. # This class handles player input for battle on the map. Some input is
  4521. # processed instantly, while some is converted into commands to be given to
  4522. # the player character.
  4523. #============================================================================
  4524.  
  4525. class Controls
  4526.  
  4527. attr_accessor :down_key
  4528. attr_accessor :left_key
  4529. attr_accessor :right_key
  4530. attr_accessor :up_key
  4531. attr_accessor :confirm_key
  4532. attr_accessor :cancel_key
  4533. attr_accessor :attack_key
  4534. attr_accessor :prevpage_key
  4535. attr_accessor :nextpage_key
  4536. attr_accessor :defend_key
  4537. attr_accessor :skill_key
  4538. attr_accessor :item_key
  4539. attr_accessor :select_key
  4540. attr_accessor :hud_key
  4541. attr_accessor :minimap_key
  4542. attr_accessor :hotkey_key
  4543. attr_accessor :run_key
  4544. attr_accessor :sneak_key
  4545. attr_accessor :jump_key
  4546. attr_accessor :turn_key
  4547.  
  4548. #--------------------------------------------------------------------------
  4549. # update
  4550. # Processes the player's input.
  4551. #--------------------------------------------------------------------------
  4552. def update
  4553. # if not allowed to act
  4554. if !$game_temp.in_battle || $game_player.jumping? ||
  4555. $game_player.freeze_action || $game_player.move_route_forcing ||
  4556. $game_player.in_action > 0 && !$game_player.ai.act.defend? ||
  4557. !$game_player.valid?
  4558. # freeze battle controls
  4559. return
  4560. end
  4561. # stop update if defending
  4562. return if update_defend
  4563. # if defending before
  4564. if $game_player.ai.act.defend?
  4565. # override defending reset
  4566. $game_player.ai.act.set
  4567. # reset action
  4568. $game_player.reset_action
  4569. # reset sprites
  4570. $game_player.reset_sprites
  4571. end
  4572. # stop update if attacking
  4573. return if update_attack
  4574. # stop update if using skill
  4575. return if update_skill
  4576. # stop update if using item
  4577. return if update_item
  4578. end
  4579. #--------------------------------------------------------------------------
  4580. # update_defend
  4581. # Processes the player's defend input.
  4582. #--------------------------------------------------------------------------
  4583. def update_defend
  4584. # continue input update if defend button not pressed
  4585. return false if !self.check_defend_condition?
  4586. # player defends
  4587. $game_player.use_defend
  4588. # setup action data
  4589. $game_player.ai.act.set(0, BlizzABS::ACTDefend, 0, 0, 1)
  4590. # stop input update
  4591. return true
  4592. end
  4593. #--------------------------------------------------------------------------
  4594. # update_attack
  4595. # Processes the player's attack input.
  4596. #--------------------------------------------------------------------------
  4597. def update_attack
  4598. # continue input update if attack should not be used
  4599. return false if !self.check_attack_condition?
  4600. # if attack not successful
  4601. if !$game_player.use_attack
  4602. # play buzzer, can't use
  4603. $game_system.se_play($data_system.buzzer_se)
  4604. end
  4605. # stop input update
  4606. return true
  4607. end
  4608. #--------------------------------------------------------------------------
  4609. # update_skill
  4610. # Processes the player's skill input.
  4611. #--------------------------------------------------------------------------
  4612. def update_skill
  4613. # continue input update if skill should be used
  4614. return false if !self.check_skill_condition?
  4615. # if skill not usable or skill use process not executed and no selection
  4616. if $game_player.battler.skill == 0 ||
  4617. !$game_player.use_skill($data_skills[$game_player.battler.skill]) &&
  4618. $game_temp.select_data == nil
  4619. # play buzzer, can't use
  4620. $game_system.se_play($data_system.buzzer_se)
  4621. end
  4622. # stop input update
  4623. return true
  4624. end
  4625. #--------------------------------------------------------------------------
  4626. # update_item
  4627. # Processes the player's item input.
  4628. #--------------------------------------------------------------------------
  4629. def update_item
  4630. # continue input if item should be used
  4631. return false if !self.check_item_condition?
  4632. # if item not usable or item use process not executed and no selection
  4633. if $game_player.battler.item == 0 ||
  4634. !$game_player.use_item($data_items[$game_player.battler.item]) &&
  4635. $game_temp.select_data == nil
  4636. # play buzzer, can't use
  4637. $game_system.se_play($data_system.buzzer_se)
  4638. end
  4639. # stop input update
  4640. return true
  4641. end
  4642. #--------------------------------------------------------------------------
  4643. # check_defend_condition?
  4644. # Checks whether defend should be executed or not.
  4645. #--------------------------------------------------------------------------
  4646. def check_defend_condition?
  4647. # defend button enabled and defend button is pressed
  4648. return ($game_system.defend_button && Input.press?(Input::Defend))
  4649. end
  4650. #--------------------------------------------------------------------------
  4651. # check_attack_condition?
  4652. # Checks whether attack should be executed or not.
  4653. #--------------------------------------------------------------------------
  4654. def check_attack_condition?
  4655. # attack button enabled and attack button is pressed
  4656. return ($game_system.attack_button && Input.trigger?(Input::Attack))
  4657. end
  4658. #--------------------------------------------------------------------------
  4659. # check_skill_condition?
  4660. # Checks whether a skill should be executed or not.
  4661. #--------------------------------------------------------------------------
  4662. def check_skill_condition?
  4663. # disallow usage if skill button disabled
  4664. return false if !$game_system.skill_button
  4665. # disallow usage
  4666. skill_condition = false
  4667. # if using direct hotkeys
  4668. if BlizzABS::Config::DIRECT_HOTKEYS
  4669. # check direct hotkeys
  4670. skill_condition = self.skill_hotkeys?
  4671. # if skill button pressed
  4672. elsif Input.trigger?(Input::Skill)
  4673. # allow usage
  4674. skill_condition = true
  4675. end
  4676. # return result
  4677. return skill_condition
  4678. end
  4679. #--------------------------------------------------------------------------
  4680. # check_item_condition?
  4681. # Checks whether a item should be executed or not.
  4682. #--------------------------------------------------------------------------
  4683. def check_item_condition?
  4684. # disallow usage if item button disabled
  4685. return false if !$game_system.item_button
  4686. # disallow usage
  4687. item_condition = false
  4688. # if using direct hotkeys
  4689. if BlizzABS::Config::DIRECT_HOTKEYS
  4690. # check direct hotkeys
  4691. item_condition = self.item_hotkeys?
  4692. # if item button pressed
  4693. elsif Input.trigger?(Input::Item)
  4694. # allow usage
  4695. item_condition = true
  4696. end
  4697. # return result
  4698. return item_condition
  4699. end
  4700. #--------------------------------------------------------------------------
  4701. # skill_hotkeys?
  4702. # Checks direct hotkey usage for skills.
  4703. #--------------------------------------------------------------------------
  4704. def skill_hotkeys?
  4705. # find all triggered keys
  4706. triggered = BlizzABS::Cache::Keys.find_all {|i|
  4707. Input.trigger?(Input::Key[i.to_s]) &&
  4708. $game_player.skill_hotkeys[i] != 0}
  4709. # no usage if usage invalid
  4710. return false if triggered.size == 0
  4711. # set as usable item
  4712. $game_player.battler.skill = $game_player.skill_hotkeys[triggered[0]]
  4713. # allow usage
  4714. return true
  4715. end
  4716. #--------------------------------------------------------------------------
  4717. # item_hotkeys?
  4718. # Checks direct hotkey usage for item.
  4719. #--------------------------------------------------------------------------
  4720. def item_hotkeys?
  4721. # find all triggered keys
  4722. triggered = BlizzABS::Cache::Keys.find_all {|i|
  4723. Input.trigger?(Input::Key[i.to_s]) &&
  4724. $game_player.item_hotkeys[i] != 0}
  4725. # no usage if usage invalid
  4726. return false if triggered.size == 0
  4727. # set as usable item
  4728. $game_player.battler.item = $game_player.item_hotkeys[triggered[0]]
  4729. # allow usage
  4730. return true
  4731. end
  4732.  
  4733. end
  4734.  
  4735. end
  4736.  
  4737. module BlizzABS
  4738.  
  4739. #============================================================================
  4740. # BlizzABS::Utility
  4741. #----------------------------------------------------------------------------
  4742. # This class provides methods for Blizz-ABS's additional capabilities that
  4743. # can't be categorized elsewhere.
  4744. #============================================================================
  4745.  
  4746. class Utility
  4747.  
  4748. # constants
  4749. SQRT_2 = Math.sqrt(2)
  4750.  
  4751. #--------------------------------------------------------------------------
  4752. # request_path
  4753. # x1 - x target coordinate of start
  4754. # y1 - y target coordinate or start
  4755. # x2 - x target coordinate of end
  4756. # y2 - y target coordinate or end
  4757. # Finds a path between points.
  4758. #--------------------------------------------------------------------------
  4759. def request_path(x1, y1, x2, y2)
  4760. return PathRequest.new(x1*pix, y1*pix, x2*pix, y2*pix)
  4761. end
  4762. #--------------------------------------------------------------------------
  4763. # get_weapon_area
  4764. # ch - map character
  4765. # d - distance
  4766. # type - area affection type
  4767. # Returns area data for the given character, range and type.
  4768. #--------------------------------------------------------------------------
  4769. def get_attack_area(ch, d, type)
  4770. return case type
  4771. when SWORD then get_circle_area(ch, d, ch.direction)
  4772. when SPEAR then get_front_area(ch, d)
  4773. when FLAIL then get_skipped_front_area(ch, d)
  4774. when BOOMERANG, BOW, BOW_ARROW, SHURIKEN then get_projectile_area(ch, d)
  4775. end
  4776. end
  4777. #--------------------------------------------------------------------------
  4778. # get_skillitem_area
  4779. # ch - map character
  4780. # d - distance
  4781. # type - area affection type
  4782. # scope - object scope
  4783. # Returns area data for the given character, range and type.
  4784. #--------------------------------------------------------------------------
  4785. def get_skillitem_area(ch, d, type, scope)
  4786. # all flag
  4787. all = (scope == 2 || scope == 4 || scope == 6)
  4788. # if circle skill
  4789. if type == HOMING || type == DIRECT || type != SHOOT &&
  4790. type != BEAM && all
  4791. # create circle area
  4792. area = get_circle_area(ch, d)
  4793. # if fullscreen skill
  4794. elsif type == BEAM && all
  4795. # create fullscreen rectangle shape
  4796. area = get_fullscreen_area
  4797. # if beam
  4798. elsif type == BEAM
  4799. # determine affection area depending on facing direction for beam area
  4800. area = get_front_area(ch, d)
  4801. else
  4802. # create affection area rectangle for projectiles
  4803. area = get_projectile_area(ch, d)
  4804. end
  4805. # return result
  4806. return area
  4807. end
  4808. #--------------------------------------------------------------------------
  4809. # get_circle_area
  4810. # ch - map character
  4811. # d - distance
  4812. # dir - direction of the circle slice if necessary
  4813. # Returns area data for the given character and range for circle area.
  4814. #--------------------------------------------------------------------------
  4815. def get_circle_area(ch, d, dir = 0)
  4816. return Circle.new(ch.real_x / 4 + 16, ch.real_y / 4 + 16, d * 32, dir)
  4817. end
  4818. #--------------------------------------------------------------------------
  4819. # get_projectile_area
  4820. # ch - map character
  4821. # d - distance
  4822. # Returns area data for the given character and range for projectiles.
  4823. #--------------------------------------------------------------------------
  4824. def get_projectile_area(ch, d)
  4825. return case ch.direction
  4826. when 2 then Rect.new(ch.real_x / 4 + 8, ch.real_y / 4 + 16, 16, d * 32)
  4827. when 4 then Rect.new(ch.real_x / 4 + 16 - d * 32, ch.real_y / 4 + 8, d * 32, 16)
  4828. when 6 then Rect.new(ch.real_x / 4 + 16, ch.real_y / 4 + 8, d * 32, 16)
  4829. when 8 then Rect.new(ch.real_x / 4 + 8, ch.real_y / 4 + 16 - d * 32, 16, d * 32)
  4830. end
  4831. end
  4832. #--------------------------------------------------------------------------
  4833. # get_projectile_hit_area
  4834. # ch - projectile character
  4835. # Returns area data for the given projectile.
  4836. #--------------------------------------------------------------------------
  4837. def get_projectile_hit_area(ch)
  4838. pix = $BlizzABS.pixel
  4839. return case ch.direction
  4840. when 2
  4841. Rect.new(ch.real_x / 4 + 8, ch.real_y / 4 + 8, 16, ch.y * 32 / pix - ch.real_y / 4 + 24)
  4842. when 4
  4843. Rect.new(ch.x * 32 / pix + 8, ch.y * 32 / pix + 8, ch.real_x / 4 - ch.x * 32 / pix + 24, 16)
  4844. when 6
  4845. Rect.new(ch.real_x / 4 + 8, ch.real_y / 4 + 8, ch.x * 32 / pix-ch.real_x / 4 + 24, 16)
  4846. when 8
  4847. Rect.new(ch.x * 32 / pix + 8, ch.y * 32 / pix + 8, 16, ch.real_y / 4 - ch.y * 32 / pix + 24)
  4848. end
  4849. end
  4850. #--------------------------------------------------------------------------
  4851. # get_front_area
  4852. # ch - map character
  4853. # d - distance
  4854. # Returns area data for the given character and range of the front area.
  4855. #--------------------------------------------------------------------------
  4856. def get_front_area(ch, d)
  4857. return case ch.direction
  4858. when 2 then Rect.new(ch.real_x / 4, ch.real_y / 4 + 16, 32, d * 32)
  4859. when 4 then Rect.new(ch.real_x / 4 + 16 - d * 32, ch.real_y / 4, d * 32, 32)
  4860. when 6 then Rect.new(ch.real_x / 4 + 16, ch.real_y / 4, d * 32, 32)
  4861. when 8 then Rect.new(ch.real_x / 4, ch.real_y / 4 + 16 - d * 32, 32, d * 32)
  4862. end
  4863. end
  4864. #--------------------------------------------------------------------------
  4865. # get_skipped_front_area
  4866. # ch - map character
  4867. # d - distance
  4868. # Returns area data for the given character and range of second half of
  4869. # the front area.
  4870. #--------------------------------------------------------------------------
  4871. def get_skipped_front_area(ch, d)
  4872. return case ch.direction
  4873. when 2 then Rect.new(ch.real_x / 4, ch.real_y / 4 + 16 + d * 16, 32, d * 16)
  4874. when 4 then Rect.new(ch.real_x / 4 + 16 - d * 32, ch.real_y / 4, d * 16, 32)
  4875. when 6 then Rect.new(ch.real_x / 4 + 16 + d * 16, ch.real_y / 4, d * 16, 32)
  4876. when 8 then Rect.new(ch.real_x / 4, ch.real_y / 4 + 16 - d * 32, 32, d * 16)
  4877. end
  4878. end
  4879. #--------------------------------------------------------------------------
  4880. # get_fullscreen_area
  4881. # Returns area data for the entire screen.
  4882. #--------------------------------------------------------------------------
  4883. def get_fullscreen_area
  4884. return Rect.new($game_map.display_x / 4, $game_map.display_y / 4, 640, 480)
  4885. end
  4886. #--------------------------------------------------------------------------
  4887. # get_scope_data
  4888. # scope - the targeting scope
  4889. # Returns the data for scopes "enemy, dead, all".
  4890. #--------------------------------------------------------------------------
  4891. def get_scope_data(scope)
  4892. return case scope
  4893. when 0 then [false, false, false]
  4894. when 1 then [true, false, false]
  4895. when 2 then [true, false, true]
  4896. when 3 then [false, false, false]
  4897. when 4 then [false, false, true]
  4898. when 5 then [false, true, false]
  4899. when 6 then [false, true, true]
  4900. when 7 then [false, false, false]
  4901. else
  4902. [false, false, false]
  4903. end
  4904. end
  4905. #--------------------------------------------------------------------------
  4906. # get_player_radius
  4907. # Returns the distance of the farthest point from the player on the
  4908. # screen.
  4909. #--------------------------------------------------------------------------
  4910. def get_player_radius
  4911. # if in the right half of the screen
  4912. if $game_player.screen_x > 320
  4913. # get screen x
  4914. x_max = $game_player.screen_x
  4915. else
  4916. # get other screen x
  4917. x_max = 640 - $game_player.screen_x
  4918. end
  4919. # if in the lower half of the screen
  4920. if $game_player.screen_y > 240
  4921. # get screen y
  4922. y_max = $game_player.screen_y
  4923. else
  4924. # get other screen y
  4925. y_max = 480 - $game_player.screen_y
  4926. end
  4927. # return distance
  4928. return Math.hypot(x_max, y_max) / 32
  4929. end
  4930. #--------------------------------------------------------------------------
  4931. # get_damage_data
  4932. # battler - battler or direct damage string
  4933. # Returns an array of colors for each damage sprite.
  4934. #--------------------------------------------------------------------------
  4935. def get_damage_data(battler)
  4936. # if not a battler
  4937. if !battler.is_a?(Game_Battler)
  4938. # if a color exists for this object
  4939. if Cache::DMGColors.has_key?(battler)
  4940. # return color and string
  4941. return [[Cache::DMGColors[battler]], [battler.to_s]]
  4942. else
  4943. # return color and string
  4944. return [[Cache::DMGColors['Default']], [battler.to_s]]
  4945. end
  4946. end
  4947. # if color cache exists
  4948. if Cache::DMGColors.has_key?(battler.damage)
  4949. # get color
  4950. colors = [Cache::DMGColors[battler.damage]]
  4951. # get string
  4952. damages = [battler.damage.to_s]
  4953. # normal damage
  4954. elsif battler.damage.is_a?(Numeric)
  4955. # no colors and no strings
  4956. colors, damages = [], []
  4957. else
  4958. # default color
  4959. colors = [Cache::DMGColors['Default']]
  4960. # get string
  4961. damages = [battler.damage.to_s]
  4962. end
  4963. # color key sign
  4964. sign = (battler.is_a?(Game_Enemy) ? 'E' : 'A')
  4965. # if HP change
  4966. if battler.hpdamage != 0
  4967. # if critical
  4968. if battler.critical
  4969. # critical damage color
  4970. colors.push(Cache::DMGColors['Critical'])
  4971. # if losing HP
  4972. elsif battler.hpdamage > 0
  4973. # normal color
  4974. colors.push(Cache::DMGColors['HP-' + sign])
  4975. elsif battler.hpdamage < 0
  4976. # normal color
  4977. colors.push(Cache::DMGColors['HP+' + sign])
  4978. end
  4979. # create damage for HP change
  4980. damages.push(battler.hpdamage.abs.to_s)
  4981. end
  4982. # if SP change
  4983. if battler.spdamage != 0
  4984. # if critical
  4985. if battler.critical
  4986. # critical damage color
  4987. colors.push(Cache::DMGColors['Critical'])
  4988. # if losing SP
  4989. elsif battler.spdamage > 0
  4990. # normal color
  4991. colors.push(Cache::DMGColors['SP-' + sign])
  4992. # if restoring SP
  4993. elsif battler.spdamage < 0
  4994. # normal color
  4995. colors.push(Cache::DMGColors['SP+' + sign])
  4996. end
  4997. # create damage for SP change
  4998. damages.push("#{battler.spdamage.abs} #{$data_system.words.sp}")
  4999. end
  5000. # return colors
  5001. return [colors, damages]
  5002. end
  5003. #--------------------------------------------------------------------------
  5004. # request_damage_sprite
  5005. # char - map character
  5006. # Requests a sprite for damage display.
  5007. #--------------------------------------------------------------------------
  5008. def request_damage_sprite(char, damage = nil)
  5009. # stop if no damage sprites flag
  5010. return if char.no_dmg_sprites
  5011. # if map battler
  5012. if damage != nil
  5013. # get damage text colors and strings
  5014. colors, damages = self.get_damage_data(damage)
  5015. else
  5016. # get damage text colors and strings
  5017. colors, damages = self.get_damage_data(char.battler)
  5018. end
  5019. # for each existing color
  5020. colors.each_index {|i|
  5021. # create one damage sprite request
  5022. $BlizzABS.cache.damages.push(DamageRequest.new(char, damages[i],
  5023. colors[i], char.battler.critical))}
  5024. end
  5025. #----------------------------------------------------------------------------
  5026. # reset_alignment_group
  5027. # id - group ID
  5028. # Resets the given alignment groups setup to default.
  5029. #----------------------------------------------------------------------------
  5030. def reset_alignment_group(id)
  5031. # create new alignment data
  5032. $game_system.alignments[id] = BlizzABS::AlignmentData.new(id)
  5033. # for all battlers of this group on the map
  5034. $game_map.battlers_group(id).each {|b|
  5035. # reset the alignment setup
  5036. b.ai.setup_group(id)
  5037. # delete moving commands
  5038. b.force_move = []
  5039. # reset the alignment setup
  5040. b.reset_action}
  5041. end
  5042. #--------------------------------------------------------------------------
  5043. # display_levelup
  5044. # actor - the actor that leveled up.
  5045. # Creates a damage sprite request for level up display.
  5046. #--------------------------------------------------------------------------
  5047. def display_levelup(actor)
  5048. # get damage text colors and strings
  5049. colors, damages = self.get_damage_data(Cache::TXTLvlUp)
  5050. # for each existing color
  5051. colors.each_index {|i|
  5052. # create one damage sprite request
  5053. $BlizzABS.cache.damages.push(DamageRequest.new(actor, damages[i],
  5054. colors[i]))}
  5055. end
  5056. #--------------------------------------------------------------------------
  5057. # intersection
  5058. # shape - either rectangle or a data array with circle data
  5059. # rect - rectangle
  5060. # Processes and test intersection of rectangles, a rectangle with a full
  5061. # circle and a rectangle with a fourth of a circle in which the user of an
  5062. # attack/skill/item is facing. The shapes get tested on whether at least
  5063. # one point of the rectangle is within the shape and if not, then this
  5064. # method checks whether the shape's characteristic lines determined by the
  5065. # center points and a few point on the borders intersect with the
  5066. # rectangle. This polygon intersection determination is a simplified
  5067. # version, sufficient for Blizz-ABS that needs less CPU time than a full
  5068. # determination algorithm.
  5069. #--------------------------------------------------------------------------
  5070. def intersection(shape, rect)
  5071. # if both are rectangles return rectangle intersection result
  5072. return rect_intersection(shape, rect) if shape.is_a?(Rect)
  5073. # temporary variables
  5074. x, y, r, d = shape.x, shape.y, shape.radius, shape.direction
  5075. # iterate through all of rectangle's points
  5076. [rect.x, rect.x+rect.width-1].each {|i| [rect.y, rect.y+rect.height-1].each {|j|
  5077. # if within special circle radius
  5078. if Math.hypot(x - i, y - j) < r ||
  5079. Math.hypot(x - i - 1, y - j) < r ||
  5080. Math.hypot(x - i, y - j - 1) < r ||
  5081. Math.hypot(x - i - 1, y - j - 1) < r
  5082. case d
  5083. when 2 then return true if j - y >= 0 && i - x <= j - y && x - i - 1 <= j - y
  5084. when 4 then return true if x - i - 1 >= 0 && j - y <= x - i - 1 && y - j - 1 <= x - i - 1
  5085. when 6 then return true if i - x >= 0 && j - y <= i - x && y - j - 1 <= i - x
  5086. when 8 then return true if y - j -1 >= 0 && i - x <= y - j - 1 && x - i - 1 <= y - j - 1
  5087. else
  5088. # full circle, intersection exists
  5089. return true
  5090. end
  5091. end}}
  5092. # initialize arrays
  5093. rects, coos, rad = [], [], (r / SQRT_2).to_i
  5094. # radius line end coordinates and rectangles depending on which circle part
  5095. case d
  5096. when 2
  5097. coos.push([x - 1 - rad, y + rad])
  5098. coos.push([2 * x - coos[0][0] - 1, coos[0][1]])
  5099. rects.push(Rect.new(x - 1, y, 2, r))
  5100. when 4
  5101. coos.push([x - 1 - rad, y - 1 - rad])
  5102. coos.push([coos[0][0], 2 * y - coos[0][1] - 1])
  5103. rects.push(Rect.new(x - r, y - 1, r, 2))
  5104. when 6
  5105. coos.push([x+rad.to_i, y - 1 - rad])
  5106. coos.push([coos[0][0], 2 * y - coos[0][1] - 1])
  5107. rects.push(Rect.new(x, y - 1, r, 2))
  5108. when 8
  5109. coos.push([x - 1 - rad, y - 1 - rad])
  5110. coos.push([2 * x - coos[0][0] - 1, coos[0][1]])
  5111. rects.push(Rect.new(x - 1, y - r, 2, r))
  5112. else
  5113. rects.push(Rect.new(x - 1, y, 2, r), Rect.new(x - r - 1, y - 1, r, 2),
  5114. Rect.new(x, y - 1, r, 2), Rect.new(x - 1, y - r - 1, 2, r))
  5115. end
  5116. # intersection exists if intersecting with any of the radius rectangles
  5117. return true if rects.any? {|rec| rect_intersection(rect, rec)}
  5118. # rectangle's border lines
  5119. top_left = [rect.x, rect.y]
  5120. bottom_right = [rect.x + rect.width - 1, rect.y + rect.height - 1]
  5121. bottom_left = [rect.x, rect.y + rect.height - 1]
  5122. top_right = [rect.x + rect.width - 1, rect.y]
  5123. # iterate through rectangle's border lines
  5124. [top_left, bottom_right].each {|i| [bottom_left, top_right].each {|j|
  5125. # iterate through the characteristic lines
  5126. coos.each {|c|
  5127. # if borderline of rectangle intersects with diagonal radius line
  5128. if line_intersection(i[0], i[1], j[0], j[1], c[0], c[1], x, y)
  5129. # intersection exists
  5130. return true
  5131. end}}}
  5132. # intersection does not exist
  5133. return false
  5134. end
  5135. #--------------------------------------------------------------------------
  5136. # rect_intersection
  5137. # r1 - rectangle 1
  5138. # r2 - rectangle 2
  5139. # Quickly determines intersection of two rectangles. It is faster than the
  5140. # algorithm to determine line intersection as both rectangles are always
  5141. # rectangles with a rotation angle of 0, 90, 180 or 270.
  5142. #--------------------------------------------------------------------------
  5143. def rect_intersection(r1, r2)
  5144. return (r1.x + r1.width > r2.x && r1.x < r2.x + r2.width &&
  5145. r1.y + r1.height > r2.y && r1.y < r2.y + r2.height)
  5146. end
  5147. #--------------------------------------------------------------------------
  5148. # line_intersection
  5149. # x1 - x-coordinate of the line 1's first point
  5150. # y1 - y-coordinate of the line 1's first point
  5151. # x1 - x-coordinate of the line 1's second point
  5152. # y1 - y-coordinate of the line 1's second point
  5153. # x1 - x-coordinate of the line 2's first point
  5154. # y1 - y-coordinate of the line 2's first point
  5155. # x1 - x-coordinate of the line 2's second point
  5156. # y1 - y-coordinate of the line 2's second point
  5157. # Uses a quick algorithm to test whether two lines intersect.
  5158. #--------------------------------------------------------------------------
  5159. def line_intersection(x1, y1, x2, y2, x3, y3, x4, y4)
  5160. # calculate vector products
  5161. d1 = (x3 - x1) * (y4 - y1) - (x4 - x1) * (y3 - y1)
  5162. d2 = (x3 - x2) * (y4 - y2) - (x4 - x2) * (y3 - y2)
  5163. d3 = (x1 - x3) * (y2 - y3) - (x2 - x3) * (y1 - y3)
  5164. d4 = (x1 - x4) * (y2 - y4) - (x2 - x4) * (y1 - y4)
  5165. # check vector product results
  5166. if (d1 > 0 && d2 < 0 || d1 < 0 && d2 > 0) &&
  5167. (d3 > 0 && d4 < 0 || d3 < 0 && d4 > 0)
  5168. # intersection exists
  5169. return true
  5170. end
  5171. # if at least one point of one line lies on the other line
  5172. if d1 == 0 && (x3 < x4 ? x3 : x4) <= x1 && x1 <= (x3 > x4 ? x3 : x4) &&
  5173. (y3 < y4 ? y3 : y4) <= y1 && y1 <= (y3 > y4 ? y3 : y4) ||
  5174. d2 == 0 && (x3 < x4 ? x3 : x4) <= x2 && x2 <= (x3 > x4 ? x3 : x4) &&
  5175. (y3 < y4 ? y3 : y4) <= y2 && y2 <= (y3 > y4 ? y3 : y4) ||
  5176. d3 == 0 && (x1 < x2 ? x1 : x2) <= x3 && x3 <= (x1 > x2 ? x1 : x2) &&
  5177. (y1 < y2 ? y1 : y2) <= y3 && y3 <= (y1 > y2 ? y1 : y2) ||
  5178. d4 == 0 && (x1 < x2 ? x1 : x2) <= x4 && x4 <= (x1 > x2 ? x1 : x2) &&
  5179. (y1 < y2 ? y1 : y2) <= y4 && y4 <= (y1 > y2 ? y1 : y2)
  5180. # intersection exists
  5181. return true
  5182. end
  5183. # intersection does not exist
  5184. return false
  5185. end
  5186. #--------------------------------------------------------------------------
  5187. # get_direction
  5188. # x - the x component
  5189. # y - the y component
  5190. # Returns the 0-9 direction corresponding to the x and y components.
  5191. #--------------------------------------------------------------------------
  5192. def get_direction(x, y)
  5193. return 0 if x == 0 && y == 0 # center
  5194. theta = (Math.atan2(y, x) * 4 / Math::PI).round
  5195. case theta
  5196. when -4 then return 4 # left
  5197. when -3 then return 1 # down left
  5198. when -2 then return 2 # down
  5199. when -1 then return 3 # down right
  5200. when 0 then return 6 # right
  5201. when 1 then return 9 # up right
  5202. when 2 then return 8 # up
  5203. when 3 then return 7 # up left
  5204. when 4 then return 4 # left
  5205. end
  5206. return 0
  5207. end
  5208. #--------------------------------------------------------------------------
  5209. # range_array_union
  5210. # a - this array of intervals
  5211. # b - other array of intervals
  5212. # Returns an array of time intervals that is the union of two other
  5213. # arrays. Both arrays' intervals are united.
  5214. #--------------------------------------------------------------------------
  5215. def range_array_union(a, b)
  5216. # convert starting numbers to ranges
  5217. a[a.size-1] = a[a.size-1]..Graphics.frame_count if a[a.size-1].is_a?(Numeric)
  5218. b[b.size-1] = b[b.size-1]..Graphics.frame_count if b[b.size-1].is_a?(Numeric)
  5219. # initialize indices
  5220. i = j = 0
  5221. # stop if either interval doesn't exist
  5222. return if a[i] == nil || b[j] == nil
  5223. # start iteration
  5224. loop do
  5225. # if both arrays' last element
  5226. if a[i + 1] == nil && b[j + 1] == nil
  5227. # if not intersecting intervals
  5228. if a[i].first > b[j].last + 1 || b[j].first > a[i].last + 1
  5229. # add both ranges sorted
  5230. a[i].first < b[j].first ? a[i + 1] = b[j] : (a[i + 1], a[i] = a[i], b[j])
  5231. else
  5232. # get range borders
  5233. min_pos = (a[i].first < b[j].first ? a[i].first : b[j].first)
  5234. max_pos = (a[i].last > b[j].last ? a[i].last : b[j].last)
  5235. # interval union is the last element
  5236. a[i] = min_pos..max_pos
  5237. end
  5238. # abort iteration
  5239. break
  5240. # if no more elements in this array
  5241. elsif a[i] == nil
  5242. # add all elements from other array
  5243. a += b[j, b.size - j]
  5244. # abort iteration
  5245. break
  5246. # if no more elements in other array
  5247. elsif b[j] == nil
  5248. # abort iteration
  5249. break
  5250. # if other intervals is after this interval
  5251. elsif b[j].first > a[i].last + 1
  5252. # check next interval of this array
  5253. i += 1
  5254. # if array is after other array or other interval is within this one
  5255. elsif a[i].first > b[j].last + 1
  5256. # add other interval into this array
  5257. a.insert(i, b[j])
  5258. # check next interval of this array
  5259. i += 1
  5260. # check next interval of other array
  5261. j += 1
  5262. elsif a[i].first >= b[j].first && a[i].last <= b[j].last
  5263. # check next interval of other array
  5264. j += 1
  5265. # if other interval starts before and ends before this interval
  5266. elsif a[i].first < b[j].first && a[i].last > b[j].last
  5267. # unite intervals
  5268. a[i] = b[j].first..a[i].last
  5269. # check next interval of other array
  5270. j += 1
  5271. # if other interval ends after this interval
  5272. else
  5273. # get range borders
  5274. min_pos = (a[i].first < b[j].first ? a[i].first : b[j].first)
  5275. # unite intervals
  5276. a[i] = min_pos..b[j].last
  5277. # as longs as intervals of this array intersect with this interval
  5278. while a[i + 1] != nil && a[i].last + 1 >= a[i + 1].first
  5279. # get range borders
  5280. max_pos = (a[i].last > a[i + 1].last ? a[i].last : a[i + 1].last)
  5281. # unite this interval and next interval of this array
  5282. a[i] = a[i].first..max_pos
  5283. # delete next interval of this array
  5284. a.delete_at(i + 1)
  5285. end
  5286. # check next interval of other array
  5287. j += 1
  5288. end
  5289. end
  5290. # if last range is a converted start number
  5291. if a.size > 0 && a[a.size - 1].last == Graphics.frame_count
  5292. # convert back
  5293. a[a.size - 1] = a[a.size - 1].first
  5294. end
  5295. end
  5296. #--------------------------------------------------------------------------
  5297. # closest_floor
  5298. # x - x start coordinate
  5299. # y - y start coordinate
  5300. # Finds the closest tile relative to the starting coordinates that does
  5301. # not have a terrain tag indicating that there is no floor beneath. If
  5302. # none is found, the method returns the starting coordinates.
  5303. #--------------------------------------------------------------------------
  5304. def closest_floor(x, y)
  5305. # create mark table and pending array
  5306. table, pending = Table.new($game_map.width, $game_map.height), [[x, y]]
  5307. # as long as there are pending coordinates
  5308. while pending.size > 0
  5309. # current coordinates
  5310. cx, cy = pending.shift
  5311. # if floor beneath
  5312. if !Config::NO_FLOOR_TAGS.include?($game_map.terrain_tag(cx, cy))
  5313. # return found coordinates
  5314. return [cx, cy]
  5315. end
  5316. # mark current coordinates as checked
  5317. table[cx, cy] = 1
  5318. # add tiles around current coordinates if they were not marked yet
  5319. pending.push([cx, cy+1]) if table[cx, cy+1] == 0
  5320. pending.push([cx-1, cy]) if table[cx-1, cy] == 0
  5321. pending.push([cx+1, cy]) if table[cx+1, cy] == 0
  5322. pending.push([cx, cy-1]) if table[cx, cy-1] == 0
  5323. end
  5324. return [x, y]
  5325. end
  5326. #--------------------------------------------------------------------------
  5327. # get_actor_skills
  5328. # actor - the actor
  5329. # Safe method to return all skills that an actor can use. It's main
  5330. # purpose is overriding so other scripts (like CRLS) can add their own
  5331. # skill sets without changing vital parts of Blizz-ABS.
  5332. #--------------------------------------------------------------------------
  5333. def get_actor_skills(actor)
  5334. return actor.skills.clone
  5335. end
  5336. #--------------------------------------------------------------------------
  5337. # decode_triggers
  5338. # list - event commands list
  5339. # Returns specified custom event triggers.
  5340. #--------------------------------------------------------------------------
  5341. def get_triggers(list)
  5342. # initialize
  5343. triggers, special = [], {}
  5344. # iteratre through all event commands
  5345. (0...list.size).each {|i|
  5346. # as long as they are comments
  5347. break if list[i].code != 108
  5348. # no ID
  5349. id = nil
  5350. # get the comment
  5351. comment = list[i].parameters[0].clone
  5352. # stop if not a trigger setup comment
  5353. break if comment.gsub!('Trigger:') {''} == nil
  5354. # get possible ID
  5355. if comment.clone.gsub!(/=(\d+)/) {"$1"} != nil
  5356. # remove the ID from the comment
  5357. comment.gsub!(/=(\d+)/) {''}
  5358. # get the ID
  5359. id = $1.to_i
  5360. end
  5361. # get actual trigger number
  5362. trigger = eval('BlizzABS::CET' + comment)
  5363. # if special trigger
  5364. if BlizzABS::CETSpecial.include?(trigger)
  5365. # if no ID specified
  5366. if id == nil
  5367. # any ID trigger
  5368. special[trigger] = []
  5369. # if first trigger of this kind
  5370. elsif !special.has_key?(trigger)
  5371. # create this special trigger with the ID
  5372. special[trigger] = [id]
  5373. # if already ecisting
  5374. elsif special[trigger].size > 0
  5375. # add this ID
  5376. special[trigger].push(id)
  5377. end
  5378. # if no normal trigger exists yet
  5379. elsif triggers.size == 0
  5380. # add the normal trigger
  5381. triggers.push(trigger)
  5382. end}
  5383. # if not triggers specified
  5384. if triggers.size == 0 && special.keys.size == 0
  5385. # return default trigger
  5386. return [BlizzABS::CETDefault, {}]
  5387. end
  5388. # add NONE trigger if no normal trigger exists
  5389. triggers.push(BlizzABS::CETNone) if triggers.size == 0
  5390. # remove duplicates
  5391. special.each_key {|key| special[key] = (special[key] | special[key])}
  5392. # add special triggers
  5393. triggers.push(special)
  5394. # return triggers
  5395. return triggers
  5396. end
  5397. #--------------------------------------------------------------------------
  5398. # add_weapon_text
  5399. # text - original text
  5400. # id - weapon ID
  5401. # type - name or description
  5402. # Generates additional data display for weapons.
  5403. #--------------------------------------------------------------------------
  5404. def add_weapon_text(text, id, type)
  5405. # return normal text if range is 0 or the option isn't for this type
  5406. return text if Weapons.range(id) == 0
  5407. # iterate through configuration
  5408. Config::WEAPON_DATA_MODE.each_index {|i|
  5409. # if current option was set up for this type
  5410. if Config::WEAPON_DATA_MODE[i] == type
  5411. # add extra information to result text
  5412. case i
  5413. when 0
  5414. text += case Weapons.type(id)
  5415. when SWORD then ' (Melee)'
  5416. when SPEAR then ' (Thrusting)'
  5417. when FLAIL then ' (Flail)'
  5418. when BOOMERANG then ' (Returning Projectile)'
  5419. when BOW then ' (Projectile)'
  5420. when BOW_ARROW then ' (Shooter)'
  5421. when SHURIKEN then ' (Throwing)'
  5422. end
  5423. when 1
  5424. number = Weapons.range(id)
  5425. number = 1 if number < 1
  5426. text += " R: #{number}"
  5427. end
  5428. end}
  5429. # return result text
  5430. return text
  5431. end
  5432. #--------------------------------------------------------------------------
  5433. # add_skill_text
  5434. # text - original text
  5435. # id - skill ID
  5436. # type - name or description
  5437. # Generates additional data display for skills.
  5438. #--------------------------------------------------------------------------
  5439. def add_skill_text(text, id, type)
  5440. # return normal text if range is 0 or the option isn't used for this type
  5441. return text if Skills.range(id) == 0
  5442. # get scope
  5443. scope = $data_skills[id].scope
  5444. # iterate through configuration
  5445. Config::SKILL_DATA_MODE.each_index {|i|
  5446. # if current option was set up for this type
  5447. if Config::SKILL_DATA_MODE[i] == type
  5448. # add extra information to result text
  5449. case i
  5450. when 0
  5451. next if scope == 0 || scope == 7
  5452. text += case Skills.type(id)[0]
  5453. when SHOOT then Cache::ScopeOne.include?(scope) ? ' (Shooter)' : ' (Thruster)'
  5454. when HOMING then Cache::ScopeOne.include?(scope) ? ' (Homing)' : ' (S. Homing)'
  5455. when DIRECT then Cache::ScopeOne.include?(scope) ? ' (Selector)' : ' (Shockwave)'
  5456. when BEAM then Cache::ScopeOne.include?(scope) ? ' (Beam)' : ' (Fullscreen)'
  5457. when TRAP then ' (Trap)'
  5458. when TIMED then ' (Timed)'
  5459. when SUMMON then ' (Summoner)'
  5460. end
  5461. when 1 then text += ' (explodes)' if Skills.type(id)[1] > 1
  5462. when 2
  5463. number = Skills.range(id)
  5464. number = 1.0 if number < 1.0
  5465. text += " R: #{number}"
  5466. end
  5467. end}
  5468. # return result text
  5469. return text
  5470. end
  5471. #--------------------------------------------------------------------------
  5472. # add_item_text
  5473. # text - original text
  5474. # id - item ID
  5475. # type - name or description
  5476. # Generates additional data display for items.
  5477. #--------------------------------------------------------------------------
  5478. def add_item_text(text, id, type)
  5479. # return normal text if range is 0 or the option isn't used for this type
  5480. return text if Items.range(id) == 0
  5481. # get scope
  5482. scope = $data_items[id].scope
  5483. # iterate through configuration
  5484. Config::ITEM_DATA_MODE.each_index {|i|
  5485. # if current option was set up for this type
  5486. if Config::ITEM_DATA_MODE[i] == type
  5487. # add extra information to result text
  5488. case i
  5489. when 0
  5490. next if scope == 0 || scope == 7
  5491. text += case Items.type(id)[0]
  5492. when SHOOT then Cache::ScopeOne.include?(scope) ? ' (Shooter)' : ' (Thruster)'
  5493. when HOMING then Cache::ScopeOne.include?(scope) ? ' (Homing)' : ' (S. Homing)'
  5494. when DIRECT then Cache::ScopeOne.include?(scope) ? ' (Selector)' : ' (Shockwave)'
  5495. when BEAM then Cache::ScopeOne.include?(scope) ? ' (Beam)' : ' (Fullscreen)'
  5496. when TRAP then ' (Trap)'
  5497. when TIMED then ' (Timed)'
  5498. when SUMMON then ' (Summoner)'
  5499. end
  5500. when 1 then text += ' (explodes)' if Items.type(id)[1] > 1
  5501. when 2
  5502. number = Items.range(id)
  5503. number = 1.0 if number < 1.0
  5504. text += " R: #{number}"
  5505. end
  5506. end}
  5507. # return result text
  5508. return text
  5509. end
  5510. #--------------------------------------------------------------------------
  5511. # animations_size_down
  5512. # Sizes down all the animations to 50%.
  5513. #--------------------------------------------------------------------------
  5514. def animations_size_down
  5515. # iterate through all animations
  5516. $data_animations[1, $data_animations.size-1].each {|animation|
  5517. # iterate through all frames and all cells
  5518. animation.frames.each {|frame| (0...frame.cell_data.xsize).each {|i|
  5519. # if cell contains image
  5520. if frame.cell_data[i, 0] != nil && frame.cell_data[i, 0] != -1
  5521. # size down x position, y position and zoom by half
  5522. (1..3).each {|j| frame.cell_data[i, j] /= 2}
  5523. end}}}
  5524. end
  5525. #--------------------------------------------------------------------------
  5526. # rotate
  5527. # old_bitmap - bitmap to rotate
  5528. # Returns a bitmap rotated by 90° counterclockwise.
  5529. #--------------------------------------------------------------------------
  5530. def rotate(old_bitmap)
  5531. # abort if no bitmap
  5532. return nil unless old_bitmap.is_a?(Bitmap)
  5533. # create new bitmap
  5534. bitmap = Bitmap.new(old_bitmap.height, old_bitmap.width)
  5535. # draw rotated
  5536. (0...old_bitmap.width).each {|x| (0...old_bitmap.height).each {|y|
  5537. # get pixel
  5538. pixel = old_bitmap.get_pixel(x, y)
  5539. # draw pixel if pixel is visible
  5540. bitmap.set_pixel(y, bitmap.height-x-1, pixel) if pixel.alpha > 0}}
  5541. # return rotated bitmap
  5542. return bitmap
  5543. end
  5544. #--------------------------------------------------------------------------
  5545. # setup_passability
  5546. # map - database map
  5547. # Returns a data hash with coordinates for the minimap drawing.
  5548. #--------------------------------------------------------------------------
  5549. def setup_passability(map)
  5550. # set map for further use and initialize
  5551. @map, result = map, Table.new(map.width, map.height)
  5552. # iterate through all each horizontal element
  5553. (0...@map.height).each {|y|
  5554. # prevent "Script is hanging" error if large map
  5555. Graphics.update if @map.height * @map.width >= 19200 && y % 10 == 0
  5556. # iterate through all each vertical element
  5557. (0...@map.width).each {|x|
  5558. # initialize value
  5559. val = 0x00
  5560. # add to value if virtually passable in each direction
  5561. val |= 0x01 if passable?(x, y, 2) && passable?(x, y+1, 8)
  5562. val |= 0x02 if passable?(x, y, 4) && passable?(x-1, y, 6)
  5563. val |= 0x04 if passable?(x, y, 6) && passable?(x+1, y, 4)
  5564. val |= 0x08 if passable?(x, y, 8) && passable?(x, y-1, 2)
  5565. # add coordinate if passable anyhow
  5566. result[x, y] = val if val != 0x00}}
  5567. # remove map from memory
  5568. @map = nil
  5569. # return passable coordinates
  5570. return result
  5571. end
  5572. #--------------------------------------------------------------------------
  5573. # passable?
  5574. # x - x-coordinate
  5575. # y - y-coordinate
  5576. # d - direction
  5577. # Checks virtual passability for the minimap.
  5578. #--------------------------------------------------------------------------
  5579. def passable?(x, y, d)
  5580. # "passable" if out of map border
  5581. return true if x < 0 || x >= @map.width || y < 0 || y >= @map.height
  5582. # set bit
  5583. bit = (1 << (d / 2 - 1)) & 0x0f
  5584. # iterate through all layers
  5585. Cache::MapLayers.each {|i|
  5586. # get tile ID
  5587. tile_id = @map.data[x, y, i]
  5588. # if tile ID not valid
  5589. if tile_id == nil
  5590. # impassable
  5591. return false
  5592. # if obstacle bit is set
  5593. elsif $data_tilesets[@map.tileset_id].passages[tile_id] & bit != 0
  5594. # impassable
  5595. return false
  5596. # if obstacle bit is set in all directions
  5597. elsif $data_tilesets[@map.tileset_id].passages[tile_id] & 0x0F == 0x0F
  5598. # impassable
  5599. return false
  5600. # if priority is 0
  5601. elsif $data_tilesets[@map.tileset_id].priorities[tile_id] == 0
  5602. # passable
  5603. return true
  5604. end}
  5605. # passable
  5606. return true
  5607. end
  5608. #--------------------------------------------------------------------------
  5609. # check_map_data
  5610. # Updates the passability file.
  5611. #--------------------------------------------------------------------------
  5612. def check_map_data
  5613. # stop if not using intelligent passability mode
  5614. return unless BlizzABS::Config::INTELLIGENT_PASSABILITY
  5615. # load tileset data
  5616. $data_tilesets = load_data('Data/Tilesets.rxdata')
  5617. # get current map states
  5618. new_data = load_data('Data/MapInfos.rxdata')
  5619. # if first time intelligent passability is being used
  5620. if !File.exist?('Data/Map_Data.abs')
  5621. # initialize
  5622. data, dates = {}, {}
  5623. # all map IDs
  5624. ids = new_data.keys.sort
  5625. else
  5626. # get passability data and "modified time" data from old data file
  5627. data, dates = load_data('Data/Map_Data.abs')
  5628. # get a sorted array of all map IDs
  5629. keys = new_data.keys.sort
  5630. # iterate through all current map IDs
  5631. keys.each_index {|i|
  5632. # if game not encrypted
  5633. if File.exist?(sprintf('Data/Map%03d.rxdata', keys[i]))
  5634. # open map file for reading
  5635. file = File.open(sprintf('Data/Map%03d.rxdata', keys[i]), 'r')
  5636. # if map was edited
  5637. if dates[keys[i]] != file.mtime
  5638. # remove map ID from data
  5639. data.delete(keys[i])
  5640. # remove map ID from dates
  5641. dates.delete(keys[i])
  5642. end
  5643. # close file
  5644. file.close
  5645. end
  5646. # prevent "Script is hanging" error
  5647. Graphics.update if i % 20 == 0}
  5648. # iterate through all map IDs that were deleted
  5649. (data.keys - keys).each {|id|
  5650. # remove map ID from data
  5651. data.delete(keys[id])
  5652. # remove map ID from dates
  5653. dates.delete(keys[id])}
  5654. # get all map IDs that need to be updated
  5655. ids = keys - data.keys
  5656. end
  5657. # iterate through all IDs
  5658. ids.each {|id|
  5659. # load map
  5660. map = load_data(sprintf('Data/Map%03d.rxdata', id))
  5661. # create one map data pack
  5662. data[id] = setup_passability(map)
  5663. # if game not encrypted
  5664. if File.exist?(sprintf('Data/Map%03d.rxdata', id))
  5665. # open map file for reading
  5666. f = File.open(sprintf('Data/Map%03d.rxdata', id), 'r')
  5667. # get map file modified time
  5668. dates[id] = f.mtime
  5669. # close file
  5670. f.close
  5671. end
  5672. # prevent "Script is hanging" error
  5673. Graphics.update}
  5674. # open new file
  5675. file = File.open('Data/Map_Data.abs', 'wb')
  5676. # save all data to file
  5677. Marshal.dump([data, dates], file)
  5678. # save and close file
  5679. file.close
  5680. # remove variables from memory completely
  5681. $data_tilesets = nil
  5682. end
  5683. end
  5684.  
  5685. end
  5686.  
  5687. module BlizzABS
  5688.  
  5689. #============================================================================
  5690. # BlizzABS::AI
  5691. #----------------------------------------------------------------------------
  5692. # This class processes Map_Enemy AI based upon AI Data, character position
  5693. # and battler status. It includes complete AI control for both actors and
  5694. # enemies.
  5695. #============================================================================
  5696.  
  5697. class AI
  5698.  
  5699. # possible AI states
  5700. Idle = 0
  5701. Request = 1
  5702. Ready = 2
  5703. Return = 3
  5704. MoveOnly = 4
  5705. Defend = 21
  5706. Escape = 22
  5707. Knockback = 30
  5708. Abort = 90
  5709. Invalid = 99
  5710.  
  5711. #==========================================================================
  5712. # BlizzABS::AI::Data
  5713. #--------------------------------------------------------------------------
  5714. # This class serves as superclass for Data classes.
  5715. #==========================================================================
  5716.  
  5717. class Data
  5718.  
  5719. # setting all accessible variables
  5720. attr_accessor :state
  5721. attr_accessor :host
  5722. attr_accessor :in_action
  5723. attr_accessor :attacked
  5724. attr_accessor :aggressive
  5725. attr_accessor :sight
  5726. attr_accessor :memory
  5727. attr_accessor :minions
  5728. attr_accessor :lead
  5729. attr_accessor :act
  5730. attr_accessor :target
  5731. attr_accessor :group
  5732. attr_accessor :negative
  5733. attr_accessor :positive
  5734. attr_accessor :neutral
  5735. attr_accessor :altered_alignment
  5736. attr_reader :attributes
  5737. attr_reader :custom
  5738. attr_reader :delay_time
  5739. attr_reader :view_range
  5740. attr_reader :hearing_range_ratio
  5741. attr_writer :observation
  5742. #------------------------------------------------------------------------
  5743. # AI initialization
  5744. #------------------------------------------------------------------------
  5745. def initialize(host, group, custom, delay, view, hear)
  5746. # set AI timers
  5747. @custom, @delay_time = custom, delay
  5748. # set Perception Range
  5749. @view_range, @hearing_range_ratio, @attributes = view, hear, 0x00
  5750. # the data carrier, battlers in sight and battler data in memory
  5751. @host, @sight, @memory = host, [], {}
  5752. # AI state for convenience and Blizz-ABS action data
  5753. @state, @act = BlizzABS::AI::Idle, BlizzABS::Action.new
  5754. # set alignment group
  5755. setup_group(group)
  5756. end
  5757. #------------------------------------------------------------------------
  5758. # setup_group
  5759. # Extra method for alignment setup.
  5760. #------------------------------------------------------------------------
  5761. def setup_group(new_group)
  5762. # original alignment
  5763. @altered_alignment = false
  5764. # set new own group
  5765. @group = new_group
  5766. # set up enemy groups
  5767. @negative = $game_system.alignments[@group].enemies.clone
  5768. # set up ally groups
  5769. @positive = $game_system.alignments[@group].allies.clone
  5770. # set up always-neutral groups
  5771. @neutral = $game_system.alignments[@group].neutral.clone
  5772. end
  5773. #------------------------------------------------------------------------
  5774. # add_to_memory
  5775. # bs - the battlers to memorize
  5776. # Memorizes all battlers and creates memory data.
  5777. #------------------------------------------------------------------------
  5778. def add_to_memory(bs)
  5779. # if array of battlers
  5780. if bs.is_a?(Array)
  5781. # add memory data for each battler
  5782. bs.each {|b| @memory[b] = MemoryData.new(b.x, b.y)}
  5783. else
  5784. # add memory data for battler
  5785. @memory[bs] = MemoryData.new(bs.x, bs.y)
  5786. end
  5787. end
  5788. #------------------------------------------------------------------------
  5789. # lifeless?
  5790. # Encapsulation method for lifeless groups.
  5791. #------------------------------------------------------------------------
  5792. def lifeless?
  5793. return BlizzABS::Alignments::LIFELESS_GROUPS.include?(@group)
  5794. end
  5795. #------------------------------------------------------------------------
  5796. # linked?
  5797. # Encapsulation method for linked groups.
  5798. #------------------------------------------------------------------------
  5799. def linked?
  5800. return BlizzABS::Alignments::LINKED_GROUPS.include?(@group)
  5801. end
  5802. #------------------------------------------------------------------------
  5803. # permanent?
  5804. # Encapsulation method for permanently linked groups.
  5805. #------------------------------------------------------------------------
  5806. def permanent?
  5807. return BlizzABS::Alignments::PERMANENT_GROUPS.include?(@group)
  5808. end
  5809. #------------------------------------------------------------------------
  5810. # origin_aggressive
  5811. # Encapsulation method for the "aggressive" attribute.
  5812. #------------------------------------------------------------------------
  5813. def origin_aggressive
  5814. return (@attributes & 0x80 == 0x00)
  5815. end
  5816. #------------------------------------------------------------------------
  5817. # actions
  5818. # Encapsulation method for the "actions" attribute.
  5819. #------------------------------------------------------------------------
  5820. def actions
  5821. return (@attributes & 0x40 == 0x40)
  5822. end
  5823. #------------------------------------------------------------------------
  5824. # observe
  5825. # Encapsulation method for the "observe" attribute.
  5826. #------------------------------------------------------------------------
  5827. def observe
  5828. return (@attributes & 0x20 == 0x20)
  5829. end
  5830. #------------------------------------------------------------------------
  5831. # defensive
  5832. # Encapsulation method for the "defensive" attribute.
  5833. #------------------------------------------------------------------------
  5834. def defensive
  5835. return (@attributes & 0x10 == 0x10)
  5836. end
  5837. #------------------------------------------------------------------------
  5838. # leader
  5839. # Encapsulation method for the "leader" attribute.
  5840. #------------------------------------------------------------------------
  5841. def leader
  5842. return (@attributes & 0x08 == 0x08)
  5843. end
  5844. #------------------------------------------------------------------------
  5845. # call_help
  5846. # Encapsulation method for the "call_help" attribute.
  5847. #------------------------------------------------------------------------
  5848. def call_help
  5849. return (@attributes & 0x04 == 0x04)
  5850. end
  5851. #------------------------------------------------------------------------
  5852. # healer
  5853. # Encapsulation method for the "healer" attribute.
  5854. #------------------------------------------------------------------------
  5855. def healer
  5856. return (@attributes & 0x02 == 0x02)
  5857. end
  5858. #------------------------------------------------------------------------
  5859. # full_power
  5860. # Encapsulation method for the "full_power" attribute.
  5861. #------------------------------------------------------------------------
  5862. def full_power
  5863. return (@attributes & 0x01 == 0x01)
  5864. end
  5865.  
  5866. end
  5867.  
  5868. #==========================================================================
  5869. # BlizzABS::AI::Data_Actor
  5870. #--------------------------------------------------------------------------
  5871. # This class holds all data important for the actor AI.
  5872. #==========================================================================
  5873.  
  5874. class Data_Actor < Data
  5875.  
  5876. #------------------------------------------------------------------------
  5877. # Initialization
  5878. #------------------------------------------------------------------------
  5879. def initialize(host)
  5880. # call superclass method
  5881. super(host, BlizzABS::Alignments::ACTOR_GROUP, false, 0, 5, 100)
  5882. end
  5883. #------------------------------------------------------------------------
  5884. # negative
  5885. # Encapsulation method since the player can attack any opponent group
  5886. # while normal actors can't.
  5887. #------------------------------------------------------------------------
  5888. def negative
  5889. # return player group enemies if self is player
  5890. return BlizzABS::Alignments::GROUPS - [@group] if @host == $game_player
  5891. # normal enemy group
  5892. return @negative
  5893. end
  5894. #------------------------------------------------------------------------
  5895. # offensive
  5896. # Encapsulation that allows the override of the offensive attribute.
  5897. #------------------------------------------------------------------------
  5898. def offensive
  5899. return (@host.battler == nil ? false : (@host.battler.force_offensive > 0 ?
  5900. @host.battler.force_offensive : @host.battler.offensive))
  5901. end
  5902. #------------------------------------------------------------------------
  5903. # aggressive
  5904. # Encapsulation that allows the override of the aggressive attribute.
  5905. #------------------------------------------------------------------------
  5906. def aggressive
  5907. return (@host.battler == nil ? false : (@host.battler.force_aggressive > 0 ?
  5908. @host.battler.force_aggressive : @host.battler.aggressive))
  5909. end
  5910. #------------------------------------------------------------------------
  5911. # delay_time
  5912. # Encapsulation that allows the override of the delay_time attribute.
  5913. # Passive allies have a higher delay.
  5914. #------------------------------------------------------------------------
  5915. def delay_time
  5916. return (self.aggressive == false ? 0 : (15 - self.aggressive) * 3)
  5917. end
  5918. #------------------------------------------------------------------------
  5919. # defensive
  5920. # Defensive actors will defend more often.
  5921. #------------------------------------------------------------------------
  5922. def defensive
  5923. return (self.offensive && self.offensive < 8)
  5924. end
  5925. #------------------------------------------------------------------------
  5926. # healer
  5927. # Defensive actors will heal more often.
  5928. #------------------------------------------------------------------------
  5929. def healer
  5930. return (self.offensive && self.offensive < 5)
  5931. end
  5932.  
  5933. end
  5934.  
  5935. #==========================================================================
  5936. # BlizzABS::AI::Data_Enemy
  5937. #--------------------------------------------------------------------------
  5938. # This class holds all data important for the enemy AI.
  5939. #==========================================================================
  5940.  
  5941. class Data_Enemy < Data
  5942.  
  5943. #------------------------------------------------------------------------
  5944. # AI initialization
  5945. #------------------------------------------------------------------------
  5946. def initialize(host, group, attributes, custom, delay, view, hear)
  5947. # call superclass method
  5948. super(host, group, custom, delay, view, hear)
  5949. # determines if enemy has an aggressive or a passive nature
  5950. @aggressive = (attributes & 0x80 == 0x00)
  5951. # set attributes and initialize minions array and observation data
  5952. @attributes, @minions, @observation = attributes, [], {}
  5953. end
  5954. #------------------------------------------------------------------------
  5955. # sight
  5956. # Encapsulation method for sight data.
  5957. #------------------------------------------------------------------------
  5958. def sight
  5959. return (@lead != nil ? @lead.ai.sight : @sight)
  5960. end
  5961. #------------------------------------------------------------------------
  5962. # memory
  5963. # Encapsulation method for memorized battlers.
  5964. #------------------------------------------------------------------------
  5965. def memory
  5966. return (@lead != nil ? @lead.ai.memory : @memory)
  5967. end
  5968. #------------------------------------------------------------------------
  5969. # observation
  5970. # Encapsulation method for observation data.
  5971. #------------------------------------------------------------------------
  5972. def observation
  5973. return (@lead != nil ? @lead.ai.observation : @observation)
  5974. end
  5975.  
  5976. end
  5977.  
  5978. #--------------------------------------------------------------------------
  5979. # wall?
  5980. # char - the character
  5981. # x - x-coordinate
  5982. # y - y-coordinate
  5983. # Checks if between the char and the target is a "wall". Walls prevent
  5984. # perception.
  5985. #--------------------------------------------------------------------------
  5986. def wall?(char, x, y)
  5987. # abort instantly if not using this option
  5988. return false if Config::WALL_TAGS.size == 0
  5989. # get pixel movement rate
  5990. pix = $BlizzABS.pixel
  5991. # get coordinate difference
  5992. dx, dy = (x-char.x)/pix, (y-char.y)/pix
  5993. # if x difference is not 0 and x difference is greater
  5994. if dx != 0 && dx.abs > dy.abs
  5995. # return any wall tile between
  5996. return (0..dx.abs).any? {|i| Config::WALL_TAGS.include?($game_map.
  5997. terrain_tag(char.x/pix+dx.sgn*i, char.y/pix+(i.to_f*dy/dx).round))}
  5998. # if y difference is not 0 and y difference is greater
  5999. elsif dy != 0 && dy.abs > dx.abs
  6000. # return any wall tile between
  6001. return (0..dy.abs).any? {|i| Config::WALL_TAGS.include?($game_map.
  6002. terrain_tag(char.x/pix+(i.to_f*dx/dy).round, char.y/pix+dy.sgn*i))}
  6003. end
  6004. # no wall between
  6005. return false
  6006. end
  6007. #--------------------------------------------------------------------------
  6008. # can_see_char?
  6009. # char - the character
  6010. # real_x - x-coordinate
  6011. # real_y - y-coordinate
  6012. # Checks if the player can be seen.
  6013. #--------------------------------------------------------------------------
  6014. def can_see_char?(char, real_x, real_y)
  6015. # calculate differences of x and y and get inner perception range
  6016. dx, dy = real_x - char.real_x, real_y - char.real_y
  6017. # check facing direction and determine whether can see or not
  6018. case char.direction
  6019. when 2 then return (dy >= 0 && dx.abs <= dy.abs)
  6020. when 4 then return (dx <= 0 && dx.abs >= dy.abs)
  6021. when 6 then return (dx >= 0 && dx.abs >= dy.abs)
  6022. when 8 then return (dy <= 0 && dx.abs <= dy.abs)
  6023. end
  6024. # can't see
  6025. return false
  6026. end
  6027. #--------------------------------------------------------------------------
  6028. # can_hear_char?
  6029. # char - the character
  6030. # real_x - x-coordinate
  6031. # real_y - y-coordinate
  6032. # Checks if the player can be heard while being close.
  6033. #--------------------------------------------------------------------------
  6034. def can_hear_char?(char, real_x, real_y)
  6035. # calculate differences of x and y and get inner perception range
  6036. dx, dy = real_x - char.real_x, real_y - char.real_y
  6037. r = char.ai.view_range * 128 * char.ai.hearing_range_ratio / 100
  6038. # can't be heard if out of range
  6039. return false if dx * dx + dy * dy > r * r
  6040. # check facing direction and determine whether can hear or not
  6041. case char.direction
  6042. when 2 then return (dy >= 0)
  6043. when 4 then return (dx <= 0)
  6044. when 6 then return (dx >= 0)
  6045. when 8 then return (dy <= 0)
  6046. end
  6047. # can't see
  6048. return false
  6049. end
  6050. #--------------------------------------------------------------------------
  6051. # can_perceive_char?
  6052. # char - the character
  6053. # real_x - x-coordinate
  6054. # real_y - y-coordinate
  6055. # Checks if the player can be heard while being close.
  6056. #--------------------------------------------------------------------------
  6057. def can_perceive_char?(char, real_x, real_y)
  6058. # calculate differences of x and y and get perception range
  6059. dx, dy = real_x - char.real_x, real_y - char.real_y
  6060. r = char.ai.view_range * 128
  6061. # can't be perceived if out of range
  6062. return (dx * dx + dy * dy <= r * r)
  6063. end
  6064. #--------------------------------------------------------------------------
  6065. # update
  6066. # char - the map character
  6067. # This is the first phase of the AI update. It determines whether a
  6068. # character is able to act at all or if an exception has occured and
  6069. # needs to expire first.
  6070. #--------------------------------------------------------------------------
  6071. def prepare(char)
  6072. # temporary variables
  6073. x, y, ai = char.x, char.y, char.ai
  6074. # if char was attacked
  6075. if char.attacked > 0
  6076. # set state
  6077. ai.state = Knockback
  6078. # stop if force moving knockback already
  6079. return if char.moving?
  6080. # if forced to move
  6081. if char.move_type == 3
  6082. # delete pending movement commands
  6083. char.force_move = []
  6084. # if not moving already
  6085. elsif !char.moving?
  6086. # add throw back moving commands
  6087. char.force_move = [Cache::FDirs[10 - char.direction]]
  6088. end
  6089. # cancel action
  6090. char.in_action = 0
  6091. # decrease attacked counter
  6092. char.attacked -= 1
  6093. # if char in action
  6094. elsif char.in_action > 0
  6095. # set state
  6096. ai.state = Abort
  6097. # if defending
  6098. if char.ai.act.defend?
  6099. # decrease shock count
  6100. char.in_action -= 1
  6101. # set state
  6102. ai.state = Defend
  6103. # if not freeze action and no action sprite
  6104. elsif !char.freeze_action && char.current_sprite == ''
  6105. # decrease shock count
  6106. char.in_action -= 1
  6107. end
  6108. # if char is moving or restricted to move
  6109. elsif char.moving? || char.restriction == 4
  6110. # set state
  6111. ai.state = (char.ai.act.escape? ? Escape : Abort)
  6112. # if char needs to move
  6113. elsif char.force_move.size > 0
  6114. # set state
  6115. ai.state = (char.ai.act.escape? ? Escape : MoveOnly)
  6116. # if target exists
  6117. elsif ai.target != nil
  6118. # set pre-state
  6119. ai.state = Ready
  6120. else
  6121. # set pre-state
  6122. ai.state = Return
  6123. end
  6124. end
  6125. #--------------------------------------------------------------------------
  6126. # perception
  6127. # char - the map character
  6128. # update_priority - determines the update priority
  6129. # This is the second phase of the AI update. It updates the character's
  6130. # perception.
  6131. #--------------------------------------------------------------------------
  6132. def perception(char, update_priority = BlizzABS::UPDFull)
  6133. # temporary variables
  6134. dir, x, y, ai, in_range = char.direction, char.x, char.y, char.ai, []
  6135. # if enemy
  6136. if char.is_a?(Map_Enemy)
  6137. # if heavy update required
  6138. if update_priority >= BlizzABS::UPDHeavy
  6139. # find all battlers within perception range
  6140. in_range = ($game_map.battlers + $BlizzABS.battlers - [char]).
  6141. find_all {|b| b.valid? && !b.battler.dead? && ai.view_range * 128 >=
  6142. Math.hypot(b.real_x-char.real_x, b.real_y-char.real_y) &&
  6143. !wall?(char, b.x, b.y)}
  6144. # find all who are in sight
  6145. ai.sight = in_range.find_all {|b| b.in_action > 0 ||
  6146. can_see_char?(char, b.real_x, b.real_y) ||
  6147. can_hear_char?(char, b.real_x, b.real_y)}
  6148. # if full update required
  6149. if update_priority == BlizzABS::UPDFull
  6150. # memorize all unmemorized, seen battlers
  6151. ai.add_to_memory(ai.sight - ai.memory.keys)
  6152. end
  6153. end
  6154. # if medium update required
  6155. if update_priority >= BlizzABS::UPDMedium
  6156. # if observing attribute is active
  6157. if ai.observe
  6158. # valid and lost actors
  6159. valid_actors, lost_actors = [], []
  6160. # for each battler in sight
  6161. ai.sight.each {|b|
  6162. # if actor
  6163. if b.is_a?(Map_Actor)
  6164. # add the appropriate array
  6165. (b.valid? ? valid_actors : lost_actors).push(b)
  6166. end}
  6167. # add all actors lost out of sight
  6168. lost_actors |= (ai.memory.keys - ai.sight).find_all {|b|
  6169. b.is_a?(Map_Actor)}
  6170. # for each actor in sight
  6171. valid_actors.each {|key|
  6172. # get observation logs
  6173. data = ai.observation[key.battler]
  6174. # if no observation log exists
  6175. if data == nil
  6176. # create an observation log
  6177. ai.observation[key.battler] = [Graphics.frame_count]
  6178. # if interval not started yet
  6179. elsif !data[data.size - 1].is_a?(Numeric)
  6180. # start observation interval right now
  6181. data.push(Graphics.frame_count)
  6182. end}
  6183. # for all actors that need to be forgotten
  6184. lost_actors.each {|key|
  6185. # get observation logs
  6186. data = ai.observation[key.battler]
  6187. # if logs exist, last log is a number and time has passed
  6188. if data != nil && data[data.size-1].is_a?(Numeric) &&
  6189. data[data.size-1] < Graphics.frame_count
  6190. # convert number into inteval
  6191. data.push(data.pop..Graphics.frame_count)
  6192. end}
  6193. end
  6194. end
  6195. # if actor
  6196. elsif char.is_a?(Map_Actor)
  6197. # in sight are all battlers in range
  6198. ai.sight = ($game_map.battlers + $BlizzABS.battlers - [char]).
  6199. find_all {|b| b.valid? && b.in_screen?}
  6200. end
  6201. # get alignment setup
  6202. negative, positive = ai.negative, ai.positive
  6203. # invert setup if confused
  6204. negative, positive = positive, negative if char.restriction == 3
  6205. # if a target exists
  6206. if ai.target != nil
  6207. # if force moving
  6208. if char.move_type == 3
  6209. # if delay counter expired
  6210. if ai.act.ready?
  6211. # execute action
  6212. try_execute(char)
  6213. # if nobody around
  6214. if ai.memory.keys.size == 0 && ai.sight.size == 0
  6215. # reset action
  6216. char.reset_action
  6217. # if about to move and target exists
  6218. elsif char.force_move.size == 0 && ai.target != nil
  6219. # get pixel movement rate and initialize flag
  6220. pix, found = $BlizzABS.pixel, false
  6221. # find the target in memory
  6222. ai.memory.each_key {|key|
  6223. # if this is the target
  6224. if key == ai.target
  6225. # if lost target completely
  6226. if ai.memory[key].x / pix == char.x / pix &&
  6227. ai.memory[key].y / pix == char.y / pix
  6228. # reset action
  6229. char.reset_action
  6230. # abort method
  6231. return
  6232. end
  6233. # found the target
  6234. found = true
  6235. break
  6236. end}
  6237. # reset action if not found in memory
  6238. char.reset_action unless found
  6239. end
  6240. end
  6241. else
  6242. # face the target
  6243. char.turn_toward(ai.target)
  6244. # if running away
  6245. if char.ai.act.escape?
  6246. # move away from reference target
  6247. char.move_away_random(ai.target, true, ai.act.range)
  6248. # if delay counter expired
  6249. elsif ai.act.ready?
  6250. # execute action
  6251. try_execute(char)
  6252. # if nobody around
  6253. if ai.memory.keys.size == 0 && ai.sight.size == 0
  6254. # reset action
  6255. char.reset_action
  6256. # if about to move and target exists
  6257. elsif char.force_move.size == 0 && ai.target != nil
  6258. # if within sight
  6259. if ai.sight.include?(ai.target)
  6260. # request path to target
  6261. request_path(char, ai.target)
  6262. else
  6263. # get pixel movement rate and initialize flag
  6264. pix, found = $BlizzABS.pixel, false
  6265. # find the target in memory
  6266. ai.memory.each_key {|key|
  6267. # if this is the target
  6268. if key == ai.target
  6269. # temporary variables
  6270. x, y = ai.memory[key].x / pix, ai.memory[key].y / pix
  6271. # if lost target completely
  6272. if x == char.x / pix && y == char.y / pix
  6273. # reset action
  6274. char.reset_action
  6275. # abort method
  6276. return
  6277. end
  6278. # find path to last known coordinates
  6279. request_path(char, x, y)
  6280. found = true
  6281. break
  6282. end}
  6283. # reset action if not found in memory
  6284. char.reset_action unless found
  6285. end
  6286. end
  6287. # if negative action and too close
  6288. elsif negative.include?(ai.target.ai.group) &&
  6289. Math.hypot(char.real_x-ai.target.real_x,
  6290. char.real_y-ai.target.real_y) < 384
  6291. # delete movement commands
  6292. char.force_move = []
  6293. # back off from reference target
  6294. if [1].include?(char.battler.id)
  6295. char.move_away_random(ai.target, false, ai.act.range)
  6296. end
  6297. # exit method
  6298. return
  6299. end
  6300. end
  6301. # if not actor
  6302. unless char.is_a?(Map_Actor)
  6303. # call for help
  6304. call_for_help(char, in_range, negative, positive)
  6305. end
  6306. end
  6307. #--------------------------------------------------------------------------
  6308. # call_for_help
  6309. # char - the map character
  6310. # in_range - array of battlers in range
  6311. # negative - perceived enemies
  6312. # positive - perceived allies
  6313. # Executes calling for help procedure.
  6314. #--------------------------------------------------------------------------
  6315. def call_for_help(char, in_range, negative, positive)
  6316. # temporary variable
  6317. ai = char.ai
  6318. # stop if confused, not help calling enemy or not newly sighted enemies
  6319. return if !ai.call_help || char.restriction == 3 || ai.target != nil
  6320. # get all enemies in sight
  6321. in_sight_e = ai.sight.find_all {|b| negative.include?(b.ai.group)}
  6322. # stop if no sighted enemies
  6323. return if in_sight_e.size == 0
  6324. # find all allied battlers
  6325. allies = in_range.find_all {|b| ai.positive.include?(b.ai.group)}
  6326. # stop if no allies exist
  6327. return if allies.size == 0
  6328. # iterate through all allies
  6329. allies.each {|ally|
  6330. # ally memorizes each battler in sight not in ally's memory already
  6331. ally.ai.add_to_memory(ai.sight - ally.ai.memory.keys)
  6332. # for each memorized battler
  6333. ai.memory.each_key {|key|
  6334. # if not memorized by ally yet
  6335. if ally.ai.memory[key] == nil
  6336. # copy memory data for battler
  6337. ally.ai.memory[key] = ai.memory[key].clone
  6338. end}
  6339. # copy real negative group to ally's negative group
  6340. ally.ai.negative = ally.ai.negative | ai.negative}
  6341. # if using help calling animation
  6342. if Config::CALL_HELP_ANIMATION_ID > 0
  6343. # setup help calling animation
  6344. char.animation_id = Config::CALL_HELP_ANIMATION_ID
  6345. end
  6346. end
  6347. #--------------------------------------------------------------------------
  6348. # decide_action
  6349. # char - the map character
  6350. # This is the fourth phase of the AI update. When a character is ready to
  6351. # act and has no action defined yet, this method decides a new action.
  6352. #--------------------------------------------------------------------------
  6353. def decide_action(char)
  6354. # temporary variables
  6355. dir, x, y, ai = char.direction, char.x, char.y, char.ai
  6356. pix = $BlizzABS.pixel
  6357. # get alignment setup
  6358. negative, positive = ai.negative, ai.positive
  6359. # invert setup if confused
  6360. negative, positive = positive, negative if char.restriction == 3
  6361. # get all enemies in sight
  6362. in_sight_e = ai.sight.find_all {|b| negative.include?(b.ai.group)}
  6363. # if no enemies are available
  6364. if in_sight_e.size == 0
  6365. # initialize
  6366. in_sight_a, in_range = [], ai.memory.keys
  6367. # get all allies and enemies in range
  6368. in_range.each {|b|
  6369. in_sight_a.push(b) if positive.include?(b.ai.group)
  6370. in_sight_e.push(b) if negative.include?(b.ai.group)}
  6371. # if still no enemies are available
  6372. if in_sight_e.size == 0
  6373. # initialize again
  6374. in_sight_a = []
  6375. # get all allies and enemies from memory
  6376. ai.memory.each_key {|b|
  6377. in_sight_a.push(b) if positive.include?(b.ai.group)
  6378. in_sight_e.push(b) if negative.include?(b.ai.group)}
  6379. end
  6380. else
  6381. # get all allies in sight
  6382. in_sight_a = ai.sight.find_all {|b| positive.include?(b.ai.group)}
  6383. end
  6384. # exit if no enemies are in sight
  6385. return if in_sight_e.size == 0
  6386. # if actor
  6387. if char.is_a?(Map_Actor)
  6388. # exit if "no enemies" are in sight
  6389. return if in_sight_e.size == 0
  6390. # get radius reach of player
  6391. rad = $BlizzABS.util.get_player_radius
  6392. # find all enemies within radius according to aggressiveness
  6393. in_radius = in_sight_e.find_all {|e|
  6394. Math.hypot(char.x / pix - e.x / pix, char.y / pix - e.y / pix) <=
  6395. rad * char.ai.aggressive / 15}
  6396. # check next trigger if action can't be executed
  6397. return if in_radius.size == 0
  6398. # add self as ally
  6399. in_sight_a.push(char)
  6400. # if confused or no trigger action was set up
  6401. if char.restriction == 3 ||
  6402. !trigger_actor_action(char, in_sight_a, in_sight_e)
  6403. # set up advanced action based on Blizz-ABS AI
  6404. advanced_actor_action(char)
  6405. end
  6406. # if enemy
  6407. elsif char.is_a?(Map_Enemy)
  6408. # if action attribute is not active
  6409. if !ai.actions
  6410. # decide normal action
  6411. char.battler.make_action
  6412. # temporary variable
  6413. act = char.battler.current_action
  6414. # set up the action in Blizz-ABS as normal action
  6415. normal_action(char, in_sight_a, in_sight_e, (act.kind == 0),
  6416. act.basic, rand(31) + 70, 80, act.skill_id)
  6417. else
  6418. # set up advanced action based on Blizz-ABS AI
  6419. advanced_enemy_action(char)
  6420. end
  6421. end
  6422. # if target doesn't exist or forced moving
  6423. if ai.target == nil || !ai.target.valid?
  6424. # reset action
  6425. char.reset_action
  6426. # if not being force moved
  6427. elsif char.is_a?(Map_Enemy) && char.move_type != 3
  6428. # set path request state
  6429. ai.state = Request
  6430. # turn toward the target not to lose it out of sight
  6431. char.turn_toward(ai.target)
  6432. # request a path
  6433. request_path(char, ai.target)
  6434. end
  6435. end
  6436. #--------------------------------------------------------------------------
  6437. # trigger_actor_action
  6438. # char - the map actor
  6439. # Analyzes what the enemy is capable of and uses that data to determine an
  6440. # action.
  6441. #--------------------------------------------------------------------------
  6442. def trigger_actor_action(char, in_sight_a, in_sight_e)
  6443. # make copies of the original perception arrays
  6444. in_sight_a_org, in_sight_e_org = in_sight_a, in_sight_e
  6445. # check each trigger
  6446. char.battler.triggers.each {|trigger|
  6447. # restore percepted battlers
  6448. in_sight_a, in_sight_e = in_sight_a_org.clone, in_sight_e_org.clone
  6449. # reset target
  6450. target = nil
  6451. # get triggering battlers
  6452. activators = case trigger.activator
  6453. when TRGLeader then [$game_player]
  6454. when TRGAlly then $BlizzABS.battlers.find_all {|b| b.valid?}
  6455. when TRGSelf then [char]
  6456. when TRGEnemy then in_sight_e.clone
  6457. when TRGProbability then nil
  6458. end
  6459. # if battler activator
  6460. if trigger.battler_activator?
  6461. # if any trigger exists
  6462. if activators.size > 0
  6463. # get a target from the trigger
  6464. target = trigger.get_a_target(char, activators)
  6465. end
  6466. # if probability worked
  6467. elsif rand(100) < trigger.value
  6468. # default target flag
  6469. target = true
  6470. end
  6471. # check next trigger if this one hasn't been activated
  6472. next if target == nil
  6473. # temporary variables
  6474. basic, type, skill, scope, id = nil, 0, false, 0, trigger.action_data
  6475. # check trigger action type
  6476. case trigger.action_type
  6477. when TRGAttack
  6478. # set attack data for later processing if can attack
  6479. basic, type, scope = true, 0, 1 if char.attack_can_use?
  6480. when TRGDefend
  6481. # set defend data for later processing
  6482. basic, type, scope = true, 1, 0
  6483. when TRGSkill
  6484. # if can use skill
  6485. if char.skill_can_use?(id)
  6486. # set skill data for later processing
  6487. basic, skill, scope = false, true, $data_skills[id].scope
  6488. end
  6489. when TRGItem
  6490. # if can use item
  6491. if char.item_can_use?(id)
  6492. # set item data for later processing
  6493. basic, scope = false, $data_items[id].scope
  6494. end
  6495. end
  6496. # check next trigger if action can't be executed
  6497. next if basic == nil
  6498. # get targeting scope data
  6499. enemy, dead, all = $BlizzABS.util.get_scope_data(scope)
  6500. # if actual target exists and not targeting multiple battlers
  6501. if target != true && !all
  6502. # if targeting enemies
  6503. if enemy
  6504. # if chosen target is not part of enemy group
  6505. unless in_sight_e.include?(target)
  6506. # get a new target
  6507. target = in_sight_e[rand(in_sight_e.size)]
  6508. end
  6509. else
  6510. # filter all dead allies if targeting dead allies
  6511. in_sight_a = in_sight_a.find_all {|a| a.battler.dead?} if dead
  6512. # if chosen target is not part of ally group
  6513. unless in_sight_a.include?(target)
  6514. # get a new target
  6515. target = in_sight_a[rand(in_sight_a.size)]
  6516. end
  6517. end
  6518. # force this target to be the only one targetable
  6519. in_sight_a, in_sight_e = [target], [target]
  6520. end
  6521. # set up action data
  6522. normal_action(char, in_sight_a, in_sight_e, basic, type,
  6523. (15 - char.ai.offensive) * 10, 0, id, skill, false)
  6524. # trigger has been activated, abort
  6525. return true}
  6526. # no trigger has been activated
  6527. return false
  6528. end
  6529. #--------------------------------------------------------------------------
  6530. # advanced_actor_action
  6531. # char - the map actor
  6532. # Analyzes what the actor is capable of and uses that data to determine an
  6533. # action.
  6534. #--------------------------------------------------------------------------
  6535. def advanced_actor_action(char)
  6536. # initialize skill action
  6537. dmg, heal, neutral = [], [], []
  6538. # iterate through all actions
  6539. $BlizzABS.util.get_actor_skills(char.battler).each {|id|
  6540. # if skill can be used
  6541. if char.skill_can_use?(id)
  6542. # if damaging skill
  6543. if $data_skills[id].power > 0
  6544. # add to array of damaging skills
  6545. dmg.push(id)
  6546. # if healing skill
  6547. elsif $data_skills[id].power < 0
  6548. # add to array of healing skills
  6549. heal.push(id)
  6550. else
  6551. # add to array of neutral skills
  6552. neutral.push(id)
  6553. end
  6554. end}
  6555. # decide a target
  6556. decide_target(char, dmg, heal, neutral, true, true, false)
  6557. end
  6558. #--------------------------------------------------------------------------
  6559. # advanced_enemy_action
  6560. # char - the map enemy
  6561. # Analyzes what the enemy is capable of and uses that data to determine an
  6562. # action.
  6563. #--------------------------------------------------------------------------
  6564. def advanced_enemy_action(char)
  6565. # initialize basic action
  6566. attack = defend = escape = false
  6567. # initialize skill action
  6568. dmg, heal, neutral = [], [], []
  6569. # iterate through all actions
  6570. char.battler.actions.each {|action|
  6571. # conditions
  6572. n = $game_temp.battle_turn
  6573. a = action.condition_turn_a
  6574. b = action.condition_turn_b
  6575. # skip if conditions are not fulfilled
  6576. next if b == 0 && n != a || b > 0 && (n < 1 || n < a || n % b != a % b)
  6577. next if char.battler.hp * 100.0 / char.battler.maxhp > action.condition_hp
  6578. next if $game_party.max_level < action.condition_level
  6579. switch_id = action.condition_switch_id
  6580. next if switch_id > 0 && !$game_switches[switch_id]
  6581. # depending on which basic type of action
  6582. case action.kind
  6583. when 0 # basic action
  6584. case action.basic
  6585. when 0 then attack = true
  6586. when 1 then defend = true
  6587. when 2 then escape = true
  6588. end
  6589. when 1 # skill action
  6590. # if skill can be used
  6591. if char.skill_can_use?(action.skill_id)
  6592. # if damaging skill
  6593. if $data_skills[action.skill_id].power > 0
  6594. # add to array of damaging skills
  6595. dmg.push(action.skill_id)
  6596. # if healing skill
  6597. elsif $data_skills[action.skill_id].power < 0
  6598. # add to array of healing skills
  6599. heal.push(action.skill_id)
  6600. else
  6601. # add to array of neutral skills
  6602. neutral.push(action.skill_id)
  6603. end
  6604. end
  6605. end}
  6606. # decide a target
  6607. decide_target(char, dmg, heal, neutral, attack, defend, escape)
  6608. end
  6609. #--------------------------------------------------------------------------
  6610. # normal_action
  6611. # char - the map character
  6612. # in_sight_a - allies in sight
  6613. # in_sight_e - enemies in sight
  6614. # basic - basic type or not
  6615. # type - which type
  6616. # def_time - defending time
  6617. # run_time - running away time
  6618. # object_id - skill ID or item ID to use
  6619. # skill - whether skill or item
  6620. # self_flag - can target self
  6621. # Used to setup the action handling depending on which action was decided
  6622. # by using the normal way without the action attribute.
  6623. #--------------------------------------------------------------------------
  6624. def normal_action(char, in_sight_a, in_sight_e, basic, type, def_time,
  6625. run_time, object_id, skill = true, self_flag = true,
  6626. forced = false)
  6627. # temporary variables
  6628. x, y, ai = char.x, char.y, char.ai
  6629. # if no data exists
  6630. if in_sight_a == nil || in_sight_e == nil
  6631. # get alignment setup
  6632. negative, positive = ai.negative, ai.positive
  6633. # invert setup if confused
  6634. negative, positive = positive, negative if char.restriction == 3
  6635. # if not basic action
  6636. unless basic
  6637. # get all allies in sight
  6638. in_sight_a = ai.sight.find_all {|b| positive.include?(b.ai.group)}
  6639. end
  6640. # get all enemies in sight
  6641. in_sight_e = ai.sight.find_all {|b| negative.include?(b.ai.group)}
  6642. end
  6643. # if basic action type
  6644. if basic
  6645. # depending on which enhanced type
  6646. case type
  6647. when ATTACK
  6648. # set AI state
  6649. ai.state = Ready
  6650. # if skill
  6651. if char.is_a?(Map_Actor)
  6652. # get weapon data
  6653. range = Weapons.range(char.battler.weapon_id)
  6654. type = Weapons.type(char.battler.weapon_id)
  6655. else
  6656. # get enemy attack data
  6657. range = Enemies.range(char.battler_id)
  6658. type = Enemies.type(char.battler_id)
  6659. end
  6660. # set action data
  6661. ai.act.set(range, ACTAttack, 0, type, ai.delay_time)
  6662. # determine a random target from all enemies in sight
  6663. ai.target = in_sight_e[rand(in_sight_e.size)]
  6664. # if being forced
  6665. if forced
  6666. # turn toward the target if target exists and not being force moved
  6667. char.turn_toward(ai.target) if ai.target != nil && char.move_type != 3
  6668. # use attack action
  6669. char.use_attack
  6670. # reset action
  6671. char.reset_action
  6672. # reset action
  6673. char.battler.current_action.clear
  6674. end
  6675. when DEFEND
  6676. # set AI state
  6677. ai.state = Defend
  6678. # target the closest enemy
  6679. ai.target = in_sight_e.min {|a, b|
  6680. Math.hypot(x - b.x, y - b.y) <=> Math.hypot(x - a.x, y - a.y)}
  6681. # turn toward the target if target exists and not being force moved
  6682. char.turn_toward(ai.target) if ai.target != nil && char.move_type != 3
  6683. # use defend action
  6684. char.use_defend
  6685. # set action data
  6686. ai.act.set(3, ACTDefend, 0, 0, def_time)
  6687. when ESCAPE
  6688. # get a reference target from which to run away
  6689. ai.target = in_sight_e[rand(in_sight_e.size)]
  6690. # if reference target exists
  6691. if ai.target != nil
  6692. # set AI state
  6693. ai.state = Escape
  6694. # set action data
  6695. ai.act.set(ai.view_range - 1, ACTEscape, 0, 0, run_time)
  6696. # stop execution
  6697. return
  6698. end
  6699. end
  6700. else
  6701. # if skill
  6702. if skill
  6703. # get skill data
  6704. range, type = Skills.range(object_id), Skills.type(object_id)[0]
  6705. # get skill and action
  6706. object, action = $data_skills[object_id], ACTSkill
  6707. else
  6708. # get item data
  6709. range, type = Items.range(object_id), Items.type(object_id)[0]
  6710. # get item and action
  6711. object, action = $data_items[object_id], ACTItem
  6712. end
  6713. # set action data
  6714. ai.act.set(range, action, object.id, type, ai.delay_time)
  6715. # if instant object
  6716. if forced || ai.act.type == SUMMON || ai.act.type != SHOOT &&
  6717. (object.scope == 0 || object.scope == 2 || object.scope == 4 ||
  6718. object.scope == 6 || object.scope == 7)
  6719. # instant execution of the skill or item
  6720. skill ? char.use_skill(object, forced) : char.use_item(object, forced)
  6721. # reset action
  6722. char.reset_action
  6723. # reset action
  6724. char.battler.current_action.clear
  6725. # if targeting enemies
  6726. elsif object.scope == 1 || object.scope == 2 && ai.act.type == SHOOT
  6727. # set an enemy target
  6728. ai.target = in_sight_e[rand(in_sight_e.size)]
  6729. # if targeting allies
  6730. elsif object.scope == 3
  6731. # add self if allowed to consider self as ally
  6732. in_sight_a += [char] if self_flag
  6733. # set an ally target
  6734. ai.target = in_sight_a[rand(in_sight_a.size)]
  6735. # if targeting dead allies
  6736. elsif object.scope == 5 && in_sight_a[0].is_a?(Map_Actor)
  6737. # set a dead ally target
  6738. ai.target = in_sight_a[rand(in_sight_a.size)]
  6739. end
  6740. end
  6741. ### 2DO
  6742. # if player with valid target
  6743. if char == $game_player && ai.target != nil
  6744. # force in_battle flag
  6745. in_battle, $game_temp.in_battle = $game_temp.in_battle, true
  6746. # force selection override
  6747. $game_temp.select_data = true
  6748. # no delay
  6749. self.try_execute(char)
  6750. # restore flag
  6751. $game_temp.in_battle = in_battle
  6752. # remove dummy selection data
  6753. $game_temp.select_data = nil
  6754. end
  6755. # if target doesn't exist or forced moving
  6756. if ai.target == nil || !ai.target.valid?
  6757. # reset action
  6758. char.reset_action
  6759. # if not being force moved
  6760. elsif char.move_type != 3
  6761. # set path request state
  6762. ai.state = Request
  6763. # turn toward the target not to lose it out of sight
  6764. char.turn_toward(ai.target)
  6765. # request a path
  6766. request_path(char, ai.target)
  6767. end
  6768. end
  6769. #--------------------------------------------------------------------------
  6770. # decide_target
  6771. # char - the map character
  6772. # dmg - damaging actions
  6773. # heal - healing actions
  6774. # neutral - actions without healing or damage
  6775. # attack - can the character attack
  6776. # defend - can the character defend
  6777. # escape - can the character escape
  6778. # This is the fifth phase of the AI update. After a character has chosen
  6779. # to perform an action, this method finds an appropriate target for the
  6780. # character.
  6781. #--------------------------------------------------------------------------
  6782. def decide_target(char, dmg, heal, neutral, attack, defend, escape)
  6783. # temporary variables
  6784. x, y, ai = char.x, char.y, char.ai
  6785. # get alignment setup
  6786. negative, positive = ai.negative, ai.positive
  6787. # invert setup if confused
  6788. negative, positive = positive, negative if char.restriction == 3
  6789. # initialize arrays
  6790. allies, enemies = [char], []
  6791. # if enemy
  6792. if char.is_a?(Map_Enemy)
  6793. # find all allies and all enemies in memory
  6794. ai.memory.each_key {|b|
  6795. allies.push(b) if positive.include?(b.ai.group)
  6796. enemies.push(b) if negative.include?(b.ai.group)}
  6797. # if actor
  6798. elsif char.is_a?(Map_Actor)
  6799. # find all allies and all enemies in sight
  6800. ai.sight.each {|b|
  6801. allies.push(b) if positive.include?(b.ai.group)
  6802. enemies.push(b) if negative.include?(b.ai.group)}
  6803. end
  6804. # find all allies who need healing
  6805. to_heal = allies.find_all {|b| b.valid? && b.battler.hp < b.battler.maxhp}
  6806. # if decided to heal
  6807. if (heal.size > 0 && to_heal.size > 0 && (ai.healer || rand(3) == 0) &&
  6808. rand(5) == 0)
  6809. # find all skills that heal all allies
  6810. allheal = heal.find_all {|id|
  6811. $data_skills[id].scope == 2 || $data_skills[id].scope == 4 ||
  6812. $data_skills[id].scope == 6}
  6813. # test again flag
  6814. test_again = true
  6815. # if more than 1 ally who needs healing exists and allheal skills exist
  6816. if to_heal.size > 1 && allheal.size > 0
  6817. # initialize data
  6818. decided, now, new = nil, [], []
  6819. # iterate through all all-healing skills
  6820. allheal.each {|id|
  6821. # fake Blizz-ABS action setup
  6822. ai.act.set(Skills.range(id), ACTSkill, id, Skills.type(id)[0],
  6823. ai.delay_time)
  6824. # all allies who can be targeted by this skill
  6825. new = to_heal.find_all {|b| $BlizzABS.can_execute?(char, b, ai.act)}
  6826. # if not decided yet
  6827. if decided == nil
  6828. # decide this skill and those allies
  6829. decided, now = id, new
  6830. # 50% chance
  6831. elsif rand(2) == 0
  6832. # intialize damage counters
  6833. dmg1 = dmg2 = 0
  6834. # sum up all damage for last decided targets
  6835. now.each {|b| dmg1 += b.battler.maxhp - b.battler.hp}
  6836. # sum up all damage for new targets
  6837. new.each {|b| dmg2 += b.battler.maxhp - b.battler.hp}
  6838. # decide this skill if it contains battlers with more damaged HP
  6839. decided, now = id, new if dmg2 > dmg1
  6840. # if more battlers would be affected by this skill
  6841. elsif new.size > now.size
  6842. # decide this skill and those allies
  6843. decided, now = id, new
  6844. end}
  6845. # if more than one battler can be healed
  6846. if now.size > 1
  6847. # setup Blizz-ABS action
  6848. ai.act.set(Skills.range(decided), ACTSkill, decided,
  6849. Skills.type(decided)[0], ai.delay_time / 2)
  6850. # don't test for one battler
  6851. test_again = false
  6852. end
  6853. end
  6854. # if should test for one battler
  6855. if test_again
  6856. # find all skills that heal one ally
  6857. oneheal = heal.find_all {|id|
  6858. $data_skills[id].scope == 1 || $data_skills[id].scope == 3 ||
  6859. $data_skills[id].scope == 5}
  6860. # if any skill exists
  6861. if oneheal.size > 0
  6862. # decided action
  6863. decided = oneheal[rand(oneheal.size)]
  6864. # decided target
  6865. ai.target = to_heal[rand(to_heal.size)]
  6866. else
  6867. # decided action
  6868. decided = heal[rand(heal.size)]
  6869. end
  6870. # stop execution if no skill decided
  6871. return false if decided == nil
  6872. # setup Blizz-ABS action
  6873. ai.act.set(Skills.range(decided), ACTSkill, decided,
  6874. Skills.type(decided)[0], ai.delay_time / 2)
  6875. end
  6876. # confirm execution
  6877. return true
  6878. end
  6879. # not decided to escape yet
  6880. escaping = false
  6881. # if able to run away
  6882. if escape && rand(5) == 0
  6883. # if observation attribute is active
  6884. if ai.observe && char.restriction != 3
  6885. # iterate through all enemies
  6886. enemies.each {|b|
  6887. # if actor
  6888. if b.is_a?(Map_Actor) && ai.observation[b.battler] != nil
  6889. # get damage per second rate
  6890. dps = get_observation(b.battler, ai.observation[b.battler].clone)
  6891. # 20% chance or damage per second-distance rate high enough
  6892. if rand(5) == 0 || dps * 128 / Math.hypot(b.real_x-
  6893. char.real_x, b.real_y-char.real_y) > char.battler.hp / 2
  6894. # set this battler as escape reference
  6895. ai.target = b
  6896. # running away
  6897. escaping = true
  6898. # abort iteration
  6899. break
  6900. end
  6901. end}
  6902. # 20% chance
  6903. elsif rand(5) == 0
  6904. # initialize minimum range
  6905. min = nil
  6906. # iterate through all enemies
  6907. enemies.each {|b|
  6908. # if closer than anybody else
  6909. if (b.is_a?(Map_Actor) && (min == nil ||
  6910. Math.hypot(b.real_x-char.real_x, b.real_y-char.real_y) < min))
  6911. # set this battler as escape reference
  6912. ai.target = b
  6913. # set new minimum range
  6914. min = Math.hypot(b.real_x-char.real_x, b.real_y-char.real_y)
  6915. # running away
  6916. escaping = true
  6917. # abort iteration
  6918. break
  6919. end}
  6920. end
  6921. end
  6922. # if decided to escape
  6923. if escaping
  6924. # set AI state
  6925. ai.state = Escape
  6926. # set action data
  6927. ai.act.set(ai.view_range - 1, ACTEscape, 0, 0, 80)
  6928. # confirm execution
  6929. return true
  6930. end
  6931. # not decided to defend yet
  6932. defending = false
  6933. # if able to defend
  6934. if defend && rand(5) == 0
  6935. # probability factor if higher if defensive and reset defend flag
  6936. factor = rand(ai.defensive ? 10 : 30)
  6937. # if decided to defend
  6938. if char.battler.hp * 100 / char.battler.maxhp < factor
  6939. # if observation attribute is active
  6940. if ai.observe && char.restriction != 3
  6941. # iterate through all enemies
  6942. enemies.each {|b|
  6943. # if actor
  6944. if b.is_a?(Map_Actor) && ai.observation[b.battler] != nil
  6945. # get damage per second rate
  6946. dps = get_observation(b.battler,
  6947. ai.observation[b.battler].clone)
  6948. # 20% chance or damage per second-distance rate high enough
  6949. if rand(5) == 0 || dps * 128 / Math.hypot(b.real_x-
  6950. char.real_x, b.real_y-char.real_y) > char.battler.hp / 3
  6951. # defending
  6952. defending = true
  6953. # abort iteration
  6954. break
  6955. end
  6956. end}
  6957. # 33% chance
  6958. elsif enemies.size > 0 && rand(5) == 0
  6959. # decided to defend
  6960. defending = true
  6961. end
  6962. end
  6963. end
  6964. # if decided to defend
  6965. if defending
  6966. # set AI state
  6967. ai.state = Defend
  6968. # target the closest enemy
  6969. ai.target = enemies.min {|a, b|
  6970. Math.hypot(x-b.x, y-b.y) <=> Math.hypot(x-a.x, y-a.y)}
  6971. # turn toward the target if target exists and not being force moved
  6972. char.turn_toward(ai.target) if ai.target != nil && char.move_type != 3
  6973. # use defend action
  6974. char.use_defend
  6975. # set action data
  6976. ai.act.set(3, ACTDefend, 0, 0, rand(31) + 70)
  6977. # confirm execution
  6978. return true
  6979. end
  6980. # number of skills
  6981. skill_number = dmg.size + heal.size + neutral.size
  6982. # if able to attack and chosen to attack
  6983. if attack && (skill_number == 0 || rand(skill_number) == 0)
  6984. # if enemy
  6985. if char.is_a?(Map_Enemy)
  6986. # set AI state
  6987. ai.state = Ready
  6988. # setup Blizz-ABS action
  6989. ai.act.set(Enemies.range(char.battler_id), ACTAttack, 0,
  6990. Enemies.type(char.battler_id), ai.delay_time)
  6991. # if observing attribute and not confused
  6992. if ai.observe && char.restriction != 3
  6993. # decide a target based upon observation experience
  6994. observation_target(char, ai, enemies)
  6995. end
  6996. # if actor
  6997. elsif char.is_a?(Map_Actor)
  6998. # set AI state
  6999. ai.state = Ready
  7000. # setup Blizz-ABS action
  7001. ai.act.set(Weapons.range(char.battler.weapon_id), ACTAttack, 0,
  7002. Weapons.type(char.battler.weapon_id), ai.delay_time)
  7003. end
  7004. # if no target exists
  7005. if ai.target == nil || !ai.target.valid?
  7006. # get any enemy
  7007. ai.target = enemies[rand(enemies.size)]
  7008. end
  7009. # confirm execution
  7010. return true
  7011. end
  7012. # decide a random skill action
  7013. decided = (dmg + neutral)[rand(dmg.size + neutral.size)]
  7014. # if action exists
  7015. if decided != nil
  7016. # if observing
  7017. if ai.observe && char.restriction != 3
  7018. # decide a target based upon observation experience
  7019. observation_target(char, ai, enemies)
  7020. end
  7021. # if no target was decided
  7022. if ai.target == nil || !ai.target.valid?
  7023. # if targeting enemies
  7024. if $data_skills[decided].scope == 0 ||
  7025. $data_skills[decided].scope == 1 ||
  7026. $data_skills[decided].scope == 2
  7027. # select a random enemy target
  7028. ai.target = enemies[rand(enemies.size)]
  7029. else
  7030. # select a random ally target
  7031. ai.target = allies[rand(allies.size)]
  7032. end
  7033. end
  7034. end
  7035. # stop execution if no target selected
  7036. return false if ai.target == nil || !ai.target.valid?
  7037. # setup Blizz-ABS action
  7038. ai.act.set(Skills.range(decided), ACTSkill, decided,
  7039. Skills.type(decided)[0], ai.delay_time)
  7040. # confirm execution
  7041. return true
  7042. end
  7043. #--------------------------------------------------------------------------
  7044. # observation_target
  7045. # char - the map character
  7046. # ai - ai of the map character
  7047. # enemies - array of enemies
  7048. # The method decide_target calls this method to decide a target based
  7049. # upon observation experience.
  7050. #--------------------------------------------------------------------------
  7051. def observation_target(char, ai, enemies)
  7052. # initialize dps array
  7053. dps = {}
  7054. # iterate through all enemies
  7055. enemies.each {|b|
  7056. # if being observed
  7057. if b.is_a?(Map_Actor) && ai.observation[b.battler] != nil
  7058. # associate battler with his dps within observation intervals
  7059. dps[b] = get_observation(b.battler, ai.observation[b.battler].clone)
  7060. end}
  7061. # find the battler closest to a dps of 1/5 of the maxhp
  7062. ai.target = dps.keys.min {|a, b|
  7063. (char.battler.maxhp/5 - dps[a]).abs <=> (char.battler.maxhp/5 - dps[b]).abs}
  7064. end
  7065. #--------------------------------------------------------------------------
  7066. # try_execute
  7067. # char - the map character
  7068. # If a character has a target defined or is about to execute a static
  7069. # action, this method controls it. It is called over and over until the
  7070. # target is within range.
  7071. #--------------------------------------------------------------------------
  7072. def try_execute(char)
  7073. # temporary variables
  7074. x, y, ai = char.x, char.y, char.ai
  7075. # if battler doesn't exist or action is not valid
  7076. if !ai.target.valid? || !ai.act.valid?
  7077. # reset movement
  7078. char.force_move = []
  7079. # reset action
  7080. char.reset_action
  7081. # abort state
  7082. ai.state = Abort
  7083. # if charging and not charged yet
  7084. elsif char.charging? && !char.charged?
  7085. # abort state
  7086. ai.state = Abort
  7087. # if character can execute action
  7088. elsif $BlizzABS.can_execute?(char)
  7089. # if attack
  7090. if ai.act.attack?
  7091. # use attack
  7092. char.use_attack
  7093. # if skill
  7094. elsif ai.act.skill?
  7095. # use skill
  7096. char.use_skill($data_skills[ai.act.id])
  7097. # if item
  7098. elsif ai.act.item?
  7099. # use item
  7100. char.use_item($data_items[ai.act.id])
  7101. end
  7102. # reset movement
  7103. char.force_move = []
  7104. # reset action
  7105. char.reset_action
  7106. # abort state
  7107. ai.state = Abort
  7108. end
  7109. end
  7110. #--------------------------------------------------------------------------
  7111. # evade_projectiles
  7112. # char - the character
  7113. # Checks whether there are projectiles that could hit the character and
  7114. # determines the reaction of the character at the threat.
  7115. #--------------------------------------------------------------------------
  7116. def evade_projectiles(char)
  7117. # temporary variable and get pixel movement rate
  7118. ai, pix = char.ai, $BlizzABS.pixel
  7119. # find all projectiles within sight or close hearing that can hit char
  7120. projectiles = $BlizzABS.cache.remotes.find_all {|p|
  7121. p.is_a?(Map_Projectile) &&
  7122. p.type != REMOnReturn && p.type != REMInitSkill &&
  7123. p.type != REMHomingSkill && p.type != REMInitItem &&
  7124. p.type != REMHomingItem && p.group.include?(ai.group)}
  7125. # filter projectiles depending on facing direction
  7126. projectiles = case char.direction
  7127. when 2 then projectiles.find_all {|p| p.real_y > char.real_y}
  7128. when 4 then projectiles.find_all {|p| p.real_x < char.real_x}
  7129. when 6 then projectiles.find_all {|p| p.real_x > char.real_x}
  7130. when 8 then projectiles.find_all {|p| p.real_y < char.real_y}
  7131. end
  7132. # if enemy
  7133. if char.is_a?(Map_Enemy)
  7134. # filter projectiles
  7135. projectiles = projectiles.find_all {|p| !wall?(char, p.x, p.y) &&
  7136. can_perceive_char?(char, p.real_x, p.real_y)}
  7137. end
  7138. # check every projectile
  7139. projectiles.each {|proj|
  7140. # create affection area rectangle for projectile
  7141. area = $BlizzABS.util.get_projectile_hit_area(proj)
  7142. # if this projectile will hit character
  7143. if $BlizzABS.util.intersection(area, char.hitbox)
  7144. # depending on how to quicker evade it
  7145. dir = case proj.direction
  7146. when 2, 8 then (char.x >= proj.x ? 6 : 4)
  7147. when 4, 6 then (char.y >= proj.y ? 2 : 8)
  7148. end
  7149. # if actually passable
  7150. if char.passable?(char.x, char.y, dir)
  7151. # move in that direction now
  7152. char.force_move.unshift(Cache::FDirs[dir])
  7153. # if passable in opposite direction
  7154. elsif char.passable?(char.x, char.y, proj.direction)
  7155. # move away now
  7156. char.force_move.unshift(Cache::FDirs[proj.direction])
  7157. end
  7158. end}
  7159. end
  7160. #--------------------------------------------------------------------------
  7161. # leader_update
  7162. # char - the leading map character
  7163. # The leader keeps updating every of his minions with the memory data of
  7164. # the other minions and shares their observation experience, so they can
  7165. # rate the actors and decide their actions better.
  7166. #--------------------------------------------------------------------------
  7167. def leader_update(char)
  7168. # temporary variable
  7169. ai = char.ai
  7170. # if not leader
  7171. if !ai.leader
  7172. # minion releases self if leader has ceased to exist
  7173. ai.lead = nil if ai.lead != nil && !ai.lead.valid?
  7174. # stop
  7175. return
  7176. end
  7177. # if confused
  7178. if char.restriction == 3
  7179. # release all minions
  7180. ai.minions.each {|b| b.ai.lead = nil}
  7181. ai.minions = []
  7182. # stop updating
  7183. return
  7184. end
  7185. # initialize
  7186. in_range, delays, override = [], [], []
  7187. # add all battlers in memory that have a matching group
  7188. ai.memory.each_key {|b| in_range.push(b) if b.ai.group == ai.group}
  7189. # release all battlers that are out of range with expired counter
  7190. (ai.minions - in_range).each {|b| b.ai.lead = nil}
  7191. # minions are allies that are not leaders and don't have leaders
  7192. ai.minions = in_range
  7193. # remove other leaders
  7194. ai.minions = in_range.find_all {|battler|
  7195. !battler.ai.leader && battler.ai.lead == nil}
  7196. # stop if no assigned minions
  7197. return if ai.minions.size == 0
  7198. # iterate through all minions
  7199. ai.minions.each {|b|
  7200. # if minion is not confused
  7201. if b.restriction != 3
  7202. # if action exists
  7203. if b.ai.act.valid?
  7204. # add delay time
  7205. delays.push(b.ai.act.ready? ? 3 : b.ai.act.delay)
  7206. # remember this minion
  7207. override.push(b)
  7208. end
  7209. # set character as leader
  7210. b.ai.lead = char
  7211. # add battlers in sight
  7212. ai.sight |= b.ai.sight
  7213. # add minion's memorized battlers not memorized by leader yet
  7214. ai.add_to_memory(b.ai.memory.keys - ai.memory.keys)
  7215. # if battler observes
  7216. if b.ai.observe
  7217. # iterate through all observed battlers
  7218. b.ai.observation.each_key {|key|
  7219. # if no data exists for this battler
  7220. if ai.observation[key] == nil
  7221. # copy data
  7222. ai.observation[key] = b.ai.observation[key]
  7223. else
  7224. # unite time intervals
  7225. $BlizzABS.util.range_array_union(ai.observation[key],
  7226. b.ai.observation[key])
  7227. end}
  7228. end
  7229. end}
  7230. # calculate average delay timer value
  7231. average = delays.sum.to_f / delays.size
  7232. # set each minion's delay timer to the average value
  7233. override.each {|b| b.ai.act.delay = average}
  7234. end
  7235. #--------------------------------------------------------------------------
  7236. # observe
  7237. # battler - the acting actor
  7238. # dmg - damage done
  7239. # Stores actor damage. It Keeps track of all actor actions for enemy
  7240. # observations.
  7241. #--------------------------------------------------------------------------
  7242. def observe(battler, dmg)
  7243. # create observer hash if none exists
  7244. @observer = {} if @observer == nil
  7245. # create battler hash if none exists
  7246. @observer[battler] = [] if @observer[battler] == nil
  7247. # if damage is numeric and there is damage
  7248. if dmg.is_a?(Numeric) && dmg != 0
  7249. # damage done at this moment if any damage done
  7250. @observer[battler].push(ObserveData.new(dmg.abs, Graphics.frame_count))
  7251. end
  7252. # remove oldest if more than 1000 logs exist for this battler
  7253. @observer[battler].shift if @observer[battler].size > 1000
  7254. end
  7255. #--------------------------------------------------------------------------
  7256. # get_observation
  7257. # battler - the requested actor
  7258. # intervals - time ranges where the actor was observed
  7259. # Returns the DPS (damage per second) rate for the given actor observed
  7260. # within the given intervals of time.
  7261. #--------------------------------------------------------------------------
  7262. def get_observation(battler, intervals = [])
  7263. # create observer hash if none exists
  7264. @observer = {} if @observer == nil
  7265. # create battler hash if none exists
  7266. @observer[battler] = [] if @observer[battler] == nil
  7267. # initialize damage, time factors and temporary variable
  7268. damage, time, tmp = 0, 1, intervals[intervals.size - 1]
  7269. # if still observing
  7270. if tmp.is_a?(Numeric)
  7271. # convert starting observation time to interval until now
  7272. intervals[intervals.size - 1] = tmp..Graphics.frame_count
  7273. end
  7274. # sum all damage within observation intervals
  7275. @observer[battler].each {|data|
  7276. damage += data.damage if intervals.any? {|int| data.time === int}}
  7277. # sum up time of observation
  7278. intervals.each {|int| time += int.last - int.first}
  7279. # return damage per second rate
  7280. return (damage * 40 / time)
  7281. end
  7282. #--------------------------------------------------------------------------
  7283. # path_requesting_parameters
  7284. # x - x target coordinate or target character
  7285. # y - y target coordinate or nothing
  7286. # Prepares the parameters for path finding requests.
  7287. #--------------------------------------------------------------------------
  7288. def path_requesting_parameters(x, y)
  7289. # if target is a character
  7290. if x.is_a?(Map_Battler)
  7291. # get pixel movement coordinates
  7292. y = x.y
  7293. x = x.x
  7294. else
  7295. # get pixel movement rate
  7296. pix = $BlizzABS.pixel
  7297. # if target is a normal character
  7298. if x.is_a?(Game_Character)
  7299. # create pixel movement coordinates from actual coordinates
  7300. y = x.y * pix
  7301. x = x.x * pix
  7302. # if actual coordinates
  7303. elsif x.is_a?(Numeric) && y.is_a?(Numeric)
  7304. # create pixel movement coordinates from actual coordinates
  7305. y *= pix
  7306. x *= pix
  7307. end
  7308. end
  7309. # return coordinates
  7310. return [x, y]
  7311. end
  7312. #--------------------------------------------------------------------------
  7313. # request_path
  7314. # a - character (point A) requesting a path
  7315. # x - x target coordinate or target character
  7316. # y - y target coordinate or nothing
  7317. # Logs requests for path finding.
  7318. #--------------------------------------------------------------------------
  7319. def request_path(a, x, y = nil)
  7320. # get target coordinates from parameters
  7321. x, y = path_requesting_parameters(x, y)
  7322. # create requesting hash if none exists
  7323. @request = {} if @request == nil
  7324. # if request does not exist yet
  7325. if a != nil && x != nil && y != nil && @request[a] == nil
  7326. # add request
  7327. @request[a] = PathRequest.new(a.x, a.y, x, y)
  7328. end
  7329. end
  7330. #--------------------------------------------------------------------------
  7331. # requesting
  7332. # char - character requesting a path
  7333. # Serves for quick determination if a character is waiting for a path to
  7334. # be calculated.
  7335. #--------------------------------------------------------------------------
  7336. def path_requesting?(char)
  7337. return (@request != nil && @request[char] != nil)
  7338. end
  7339. #--------------------------------------------------------------------------
  7340. # update
  7341. # Here is where the path calculation and observation is being done. The
  7342. # observer updates the data and the pathfinder calculation is being
  7343. # executed 5 times. It is called every frame while on the map.
  7344. #--------------------------------------------------------------------------
  7345. def update
  7346. # create observer hash if none exists
  7347. @observer = {} if @observer == nil
  7348. # remove all observed actors that are not in the party (to save memory)
  7349. @observer.clone.each_key {|battler|
  7350. @observer.delete(battler) unless $game_party.actors.include?(battler)}
  7351. # create requesting hash if none exists
  7352. @request = {} if @request == nil
  7353. # get an array of all requesting characters
  7354. characters = @request.keys
  7355. # max of 4 calculations per frame to avoid lag
  7356. count = 4
  7357. # start calculation
  7358. while characters.size > 0 && count > 0
  7359. # get a hash key
  7360. char = characters.shift
  7361. # do path calculation for this character and his target
  7362. result = find_path(char)
  7363. # if result exists, add path to character, else add character to query
  7364. result != nil ? char.force_move = result : characters.push(char)
  7365. # decrease countdown
  7366. count -= 1
  7367. end
  7368. end
  7369. #--------------------------------------------------------------------------
  7370. # find_path
  7371. # char - character requesting a path
  7372. # Implementation of the A* algorithm. It tests only one node and is called
  7373. # only 5 times per frame to prevent lag.
  7374. #--------------------------------------------------------------------------
  7375. def find_path(char)
  7376. # get pixel movement rate
  7377. pix = $BlizzABS.pixel
  7378. # use request
  7379. request = @request[char]
  7380. # if no nodes to test
  7381. if request.open.size == 0
  7382. # abort testing for this character
  7383. @request.delete(char)
  7384. # resets state
  7385. char.ai.state = (char.ai.state == Invalid ? Return : Ready)
  7386. # stop execution
  7387. return []
  7388. end
  7389. # found
  7390. found = false
  7391. # find minimal key
  7392. key = request.open.keys.min {|a, b|
  7393. Math.hypot(a[0] - request.tx, a[1] - request.ty) <=>
  7394. Math.hypot(b[0] - request.tx, b[1] - request.ty)}
  7395. # this node is now logged as checked
  7396. request.closed[key[0], key[1]] = request.open[key]
  7397. # remove this node from the pending array
  7398. request.open.delete(key)
  7399. # iterate through all possible directions with relative offsets
  7400. Cache::PathDirs.each {|dir|
  7401. # coordinates of new position
  7402. kx, ky = key[0] + dir[0], key[1] + dir[1]
  7403. # if new coordinates are destination
  7404. if kx == request.tx && ky == request.ty
  7405. # the new node was checked
  7406. request.closed[kx, ky] = dir[2]
  7407. # path was found
  7408. found = true
  7409. # stop checking
  7410. break
  7411. # if new node not checked yet and coordinates are passable
  7412. elsif request.closed[kx, ky] == 0 &&
  7413. char.passable?(key[0] * pix, key[1] * pix, dir[2])
  7414. # add new node to be checked
  7415. request.open[[kx, ky]] = dir[2]
  7416. end}
  7417. # stop execution except if found path
  7418. return nil unless found
  7419. # backtrack the path
  7420. result = request.backtrack
  7421. # finish testing for this character
  7422. @request.delete(char)
  7423. # resets state
  7424. char.ai.state = (char.ai.state == Invalid ? Return : Ready)
  7425. # return movement command array
  7426. return result
  7427. end
  7428.  
  7429. end
  7430.  
  7431. end
  7432.  
  7433. # load Blizz-ABS Processor
  7434. $BlizzABS = BlizzABS::Processor.new
  7435.  
  7436. #==============================================================================
  7437. # module Input
  7438. #==============================================================================
  7439.  
  7440. module Input
  7441.  
  7442. #----------------------------------------------------------------------------
  7443. # Simple ASCII table
  7444. #----------------------------------------------------------------------------
  7445. Key = {'A' => 65, 'B' => 66, 'C' => 67, 'D' => 68, 'E' => 69, 'F' => 70,
  7446. 'G' => 71, 'H' => 72, 'I' => 73, 'J' => 74, 'K' => 75, 'L' => 76,
  7447. 'M' => 77, 'N' => 78, 'O' => 79, 'P' => 80, 'Q' => 81, 'R' => 82,
  7448. 'S' => 83, 'T' => 84, 'U' => 85, 'V' => 86, 'W' => 87, 'X' => 88,
  7449. 'Y' => 89, 'Z' => 90,
  7450. '0' => 48, '1' => 49, '2' => 50, '3' => 51, '4' => 52, '5' => 53,
  7451. '6' => 54, '7' => 55, '8' => 56, '9' => 57,
  7452. 'NumberPad 0' => 45, 'NumberPad 1' => 35, 'NumberPad 2' => 40,
  7453. 'NumberPad 3' => 34, 'NumberPad 4' => 37, 'NumberPad 5' => 12,
  7454. 'NumberPad 6' => 39, 'NumberPad 7' => 36, 'NumberPad 8' => 38,
  7455. 'NumberPad 9' => 33,
  7456. 'F1' => 112, 'F2' => 113, 'F3' => 114, 'F4' => 115, 'F5' => 116,
  7457. 'F6' => 117, 'F7' => 118, 'F8' => 119, 'F9' => 120, 'F10' => 121,
  7458. 'F11' => 122, 'F12' => 123,
  7459. ';' => 186, '=' => 187, ',' => 188, '-' => 189, '.' => 190, '/' => 220,
  7460. '\\' => 191, '\'' => 222, '[' => 219, ']' => 221, '`' => 192,
  7461. 'Backspace' => 8, 'Tab' => 9, 'Enter' => 13, 'Shift' => 16,
  7462. 'Left Shift' => 160, 'Right Shift' => 161, 'Left Ctrl' => 162,
  7463. 'Right Ctrl' => 163, 'Left Alt' => 164, 'Right Alt' => 165,
  7464. 'Ctrl' => 17, 'Alt' => 18, 'Esc' => 27, 'Space' => 32, 'Page Up' => 33,
  7465. 'Page Down' => 34, 'End' => 35, 'Home' => 36, 'Insert' => 45,
  7466. 'Delete' => 46, 'Arrow Left' => 37, 'Arrow Up' => 38,
  7467. 'Arrow Right' => 39, 'Arrow Down' => 40,
  7468. 'Mouse Left' => 1, 'Mouse Right' => 2, 'Mouse Middle' => 4,
  7469. 'Mouse 4' => 5, 'Mouse 5' => 6}
  7470. # default button configuration
  7471. UP = [Key['Arrow Up']]
  7472. LEFT = [Key['Arrow Left']]
  7473. DOWN = [Key['Arrow Down']]
  7474. RIGHT = [Key['Arrow Right']]
  7475. A = [Key['Shift']]
  7476. B = [Key['Esc'], Key['NumberPad 0'], Key['X']]
  7477. C = [Key['Space'], Key['Enter'], Key['C']]
  7478. X = [Key['A']]
  7479. Y = [Key['S']]
  7480. Z = [Key['D']]
  7481. L = [Key['Q'], Key['Page Down']]
  7482. R = [Key['W'], Key['Page Up']]
  7483. F5 = [Key['F5']]
  7484. F6 = [Key['F6']]
  7485. F7 = [Key['F7']]
  7486. F8 = [Key['F8']]
  7487. F9 = [Key['F9']]
  7488. SHIFT = [Key['Shift']]
  7489. CTRL = [Key['Ctrl']]
  7490. ALT = [Key['Alt']]
  7491. # All keys
  7492. ALL_KEYS = (0...256).to_a
  7493. # Win32 API calls
  7494. GetKeyboardState = Win32API.new('user32','GetKeyboardState', 'P', 'I')
  7495. GetKeyboardLayout = Win32API.new('user32', 'GetKeyboardLayout','L', 'L')
  7496. MapVirtualKeyEx = Win32API.new('user32', 'MapVirtualKeyEx', 'IIL', 'I')
  7497. ToUnicodeEx = Win32API.new('user32', 'ToUnicodeEx', 'LLPPILL', 'L')
  7498. # some other constants
  7499. DOWN_STATE_MASK = 0x80
  7500. DEAD_KEY_MASK = 0x80000000
  7501. # data
  7502. @state = "\0" * 256
  7503. @triggered = Array.new(256, false)
  7504. @pressed = Array.new(256, false)
  7505. @released = Array.new(256, false)
  7506. @repeated = Array.new(256, 0)
  7507. #----------------------------------------------------------------------------
  7508. # update
  7509. # Updates input.
  7510. #----------------------------------------------------------------------------
  7511. def self.update
  7512. # get current language layout
  7513. @language_layout = GetKeyboardLayout.call(0)
  7514. # get new keyboard state
  7515. GetKeyboardState.call(@state)
  7516. # for each key
  7517. ALL_KEYS.each {|key|
  7518. # if pressed state
  7519. if @state[key] & DOWN_STATE_MASK == DOWN_STATE_MASK
  7520. # not released anymore
  7521. @released[key] = false
  7522. # if not pressed yet
  7523. if !@pressed[key]
  7524. # pressed and triggered
  7525. @pressed[key] = true
  7526. @triggered[key] = true
  7527. else
  7528. # not triggered anymore
  7529. @triggered[key] = false
  7530. end
  7531. # update of repeat counter
  7532. @repeated[key] < 17 ? @repeated[key] += 1 : @repeated[key] = 15
  7533. # not released yet
  7534. elsif !@released[key]
  7535. # if still pressed
  7536. if @pressed[key]
  7537. # not triggered, pressed or repeated, but released
  7538. @triggered[key] = false
  7539. @pressed[key] = false
  7540. @repeated[key] = 0
  7541. @released[key] = true
  7542. end
  7543. else
  7544. # not released anymore
  7545. @released[key] = false
  7546. end}
  7547. end
  7548. #----------------------------------------------------------------------------
  7549. # dir4
  7550. # 4 direction check.
  7551. #----------------------------------------------------------------------------
  7552. def Input.dir4
  7553. return 2 if Input.press?(DOWN)
  7554. return 4 if Input.press?(LEFT)
  7555. return 6 if Input.press?(RIGHT)
  7556. return 8 if Input.press?(UP)
  7557. return 0
  7558. end
  7559. #----------------------------------------------------------------------------
  7560. # dir8
  7561. # 8 direction check.
  7562. #----------------------------------------------------------------------------
  7563. def Input.dir8
  7564. down = Input.press?(DOWN)
  7565. left = Input.press?(LEFT)
  7566. return 1 if down && left
  7567. right = Input.press?(RIGHT)
  7568. return 3 if down && right
  7569. up = Input.press?(UP)
  7570. return 7 if up && left
  7571. return 9 if up && right
  7572. return 2 if down
  7573. return 4 if left
  7574. return 6 if right
  7575. return 8 if up
  7576. return 0
  7577. end
  7578. #----------------------------------------------------------------------------
  7579. # trigger?
  7580. # Test if key was triggered once.
  7581. #----------------------------------------------------------------------------
  7582. def Input.trigger?(keys)
  7583. keys = [keys] unless keys.is_a?(Array)
  7584. return keys.any? {|key| @triggered[key]}
  7585. end
  7586. #----------------------------------------------------------------------------
  7587. # press?
  7588. # Test if key is being pressed.
  7589. #----------------------------------------------------------------------------
  7590. def Input.press?(keys)
  7591. keys = [keys] unless keys.is_a?(Array)
  7592. return keys.any? {|key| @pressed[key]}
  7593. end
  7594. #----------------------------------------------------------------------------
  7595. # repeat?
  7596. # Test if key is being pressed for repeating.
  7597. #----------------------------------------------------------------------------
  7598. def Input.repeat?(keys)
  7599. keys = [keys] unless keys.is_a?(Array)
  7600. return keys.any? {|key| @repeated[key] == 1 || @repeated[key] == 16}
  7601. end
  7602. #----------------------------------------------------------------------------
  7603. # release?
  7604. # Test if key was released.
  7605. #----------------------------------------------------------------------------
  7606. def Input.release?(keys)
  7607. keys = [keys] unless keys.is_a?(Array)
  7608. return keys.any? {|key| @released[key]}
  7609. end
  7610. #----------------------------------------------------------------------------
  7611. # get_character
  7612. # vk - virtual key
  7613. # Gets the character from keyboard input using the input locale identifier
  7614. # (formerly called keyboard layout handles).
  7615. #----------------------------------------------------------------------------
  7616. def self.get_character(vk)
  7617. # get corresponding character from virtual key
  7618. c = MapVirtualKeyEx.call(vk, 2, @language_layout)
  7619. # stop if character is non-printable and not a dead key
  7620. return '' if c < 32 && (c & DEAD_KEY_MASK != DEAD_KEY_MASK)
  7621. # get scan code
  7622. vsc = MapVirtualKeyEx.call(vk, 0, @language_layout)
  7623. # result string is never longer than 2 bytes (Unicode)
  7624. result = "\0" * 2
  7625. # get input string from Win32 API
  7626. length = ToUnicodeEx.call(vk, vsc, @state, result, 2, 0, @language_layout)
  7627. return (length == 0 ? '' : result)
  7628. end
  7629. #----------------------------------------------------------------------------
  7630. # get_input_string
  7631. # Gets the string that was entered using the keyboard over the input locale
  7632. # identifier (formerly called keyboard layout handles).
  7633. #----------------------------------------------------------------------------
  7634. def self.get_input_string
  7635. result = ''
  7636. # check every key
  7637. ALL_KEYS.each {|key|
  7638. # if repeated
  7639. if self.repeat?(key)
  7640. # get character from keyboard state
  7641. c = self.get_character(key)
  7642. # add character if there is a character
  7643. result += c if c != ''
  7644. end}
  7645. # empty if result is empty
  7646. return '' if result == ''
  7647. # convert string from Unicode to UTF-8
  7648. return self.unicode_to_utf8(result)
  7649. end
  7650. #----------------------------------------------------------------------------
  7651. # get_input_string
  7652. # string - string in Unicode format
  7653. # Converts a string from Unicode format to UTF-8 format as RGSS does not
  7654. # support Unicode.
  7655. #----------------------------------------------------------------------------
  7656. def self.unicode_to_utf8(string)
  7657. result = ''
  7658. string.unpack('S*').each {|c|
  7659. # characters under 0x80 are 1 byte characters
  7660. if c < 0x0080
  7661. result += c.chr
  7662. # other characters under 0x800 are 2 byte characters
  7663. elsif c < 0x0800
  7664. result += (0xC0 | (c >> 6)).chr
  7665. result += (0x80 | (c & 0x3F)).chr
  7666. # the rest are 3 byte characters
  7667. else
  7668. result += (0xE0 | (c >> 12)).chr
  7669. result += (0x80 | ((c >> 12) & 0x3F)).chr
  7670. result += (0x80 | (c & 0x3F)).chr
  7671. end}
  7672. return result
  7673. end
  7674.  
  7675. end
  7676.  
  7677. #==============================================================================
  7678. # module Input
  7679. #------------------------------------------------------------------------------
  7680. # Added Blizz-ABS controls and control override.
  7681. #==============================================================================
  7682.  
  7683. module Input
  7684.  
  7685. # Blizz-ABS control setup
  7686. if BlizzABS::Control::CUSTOM_CONTROLS
  7687. eval("Up = [#{BlizzABS::Control::UP}]")
  7688. eval("Left = [#{BlizzABS::Control::LEFT}]")
  7689. eval("Down = [#{BlizzABS::Control::DOWN}]")
  7690. eval("Right = [#{BlizzABS::Control::RIGHT}]")
  7691. eval("Prevpage = [#{BlizzABS::Control::PREVPAGE}]")
  7692. eval("Nextpage = [#{BlizzABS::Control::NEXTPAGE}]")
  7693. eval("Confirm = [#{BlizzABS::Control::CONFIRM}]")
  7694. eval("Cancel = [#{BlizzABS::Control::CANCEL}]")
  7695. eval("Attack = [#{BlizzABS::Control::ATTACK}]")
  7696. eval("Defend = [#{BlizzABS::Control::DEFEND}]")
  7697. eval("Skill = [#{BlizzABS::Control::SKILL}]")
  7698. eval("Item = [#{BlizzABS::Control::ITEM}]")
  7699. eval("Select = [#{BlizzABS::Control::SELECT}]")
  7700. eval("Hud = [#{BlizzABS::Control::HUD}]")
  7701. eval("Hotkey = [#{BlizzABS::Control::HOTKEY}]")
  7702. eval("Minimap = [#{BlizzABS::Control::MINIMAP}]")
  7703. eval("Run = [#{BlizzABS::Control::RUN}]")
  7704. eval("Sneak = [#{BlizzABS::Control::SNEAK}]")
  7705. eval("Jump = [#{BlizzABS::Control::JUMP}]")
  7706. eval("Turn = [#{BlizzABS::Control::TURN}]")
  7707. # default controls
  7708. else
  7709. Up = [Key['W']]
  7710. Left = [Key['A']]
  7711. Down = [Key['S']]
  7712. Right = [Key['D']]
  7713. Prevpage = [Key['Q']]
  7714. Nextpage = [Key['E']]
  7715. Confirm = [Key['H']]
  7716. Cancel = [Key['F']]
  7717. Attack = [Key['K']]
  7718. Defend = [Key['L']]
  7719. Skill = [Key['J']]
  7720. Item = [Key['I']]
  7721. Select = [Key['O']]
  7722. Hud = [Key['Z']]
  7723. Hotkey = [Key['X']]
  7724. Minimap = [Key['C']]
  7725. Run = [Key['M']]
  7726. Sneak = [Key['.']]
  7727. Jump = [Key[',']]
  7728. Turn = [Key['U']]
  7729. end
  7730. if BlizzABS::Control::DISABLE_DEFAULT
  7731. UP = Up
  7732. LEFT = Left
  7733. DOWN = Down
  7734. RIGHT = Right
  7735. B = Cancel
  7736. C = Confirm
  7737. L = Prevpage
  7738. R = Nextpage
  7739. else
  7740. UP |= Up
  7741. LEFT |= Left
  7742. DOWN |= Down
  7743. RIGHT |= Right
  7744. B = (B - [Key['X']]) | Cancel
  7745. C = (C - [Key['C']]) | Confirm
  7746. L = (L - [Key['Page Down']]) | Prevpage
  7747. R = (R - [Key['Page Up']]) | Nextpage
  7748. end
  7749.  
  7750. end
  7751.  
  7752. #==============================================================================
  7753. # Numeric
  7754. #------------------------------------------------------------------------------
  7755. # This class serves as superclass for all numbers. It was enhanced with a
  7756. # utility method.
  7757. #==============================================================================
  7758.  
  7759. class Numeric
  7760.  
  7761. #--------------------------------------------------------------------------
  7762. # sgn
  7763. # Returns the sign of the number or 0 if the number is 0.
  7764. #--------------------------------------------------------------------------
  7765. def sgn
  7766. return (self == 0 ? 0 : self / self.abs)
  7767. end
  7768.  
  7769. end
  7770.  
  7771. #==============================================================================
  7772. # Array
  7773. #------------------------------------------------------------------------------
  7774. # This class handles array data structures. It was modified to support the
  7775. # utility operations sum and squares.
  7776. #==============================================================================
  7777.  
  7778. class Array
  7779.  
  7780. #----------------------------------------------------------------------------
  7781. # sum
  7782. # Sums up all the numeric values of the array.
  7783. #----------------------------------------------------------------------------
  7784. def sum
  7785. # initialize
  7786. sum = 0
  7787. # add each element that's a number to sum
  7788. self.each {|i| sum += i if i.is_a?(Numeric)}
  7789. # return sum as float
  7790. return sum
  7791. end
  7792.  
  7793. end
  7794.  
  7795. #==============================================================================
  7796. # Hash
  7797. #------------------------------------------------------------------------------
  7798. # This class handles hash data structures. It was modified to support the
  7799. # utility operations sum and squares.
  7800. #==============================================================================
  7801.  
  7802. class Hash
  7803.  
  7804. #----------------------------------------------------------------------------
  7805. # sum
  7806. # Sums up all the numeric values of the array.
  7807. #----------------------------------------------------------------------------
  7808. def sum
  7809. # initialize
  7810. sum = 0
  7811. # add each element that's a number to sum
  7812. self.each_value {|i| sum += i if i.is_a?(Numeric)}
  7813. # return sum as float
  7814. return sum
  7815. end
  7816.  
  7817. end
  7818.  
  7819. #============================================================================
  7820. # Circle
  7821. #----------------------------------------------------------------------------
  7822. # This class represents a circle.
  7823. #============================================================================
  7824.  
  7825. class Circle
  7826.  
  7827. # setting all accessible variables
  7828. attr_accessor :x
  7829. attr_accessor :y
  7830. attr_accessor :radius
  7831. attr_accessor :direction
  7832. #--------------------------------------------------------------------------
  7833. # Initialization
  7834. # x - center x-coordinate
  7835. # y - center y-coordinate
  7836. # radius - circle radius
  7837. #--------------------------------------------------------------------------
  7838. def initialize(x = 0, y = 0, radius = 1, direction = 0)
  7839. @x, @y, @radius, @direction = x, y, radius, direction
  7840. end
  7841.  
  7842. end
  7843.  
  7844. #==============================================================================
  7845. # Sprite
  7846. #------------------------------------------------------------------------------
  7847. # This class was enhanced with quick color access, a critical animation flag
  7848. # and special viewport coordinate calculation that is used by all HUD
  7849. # elements.
  7850. #==============================================================================
  7851.  
  7852. class Sprite
  7853.  
  7854. # setting all accessible variables
  7855. attr_accessor :critical
  7856. #----------------------------------------------------------------------------
  7857. # system_color
  7858. # Returns the system color.
  7859. #----------------------------------------------------------------------------
  7860. def system_color
  7861. return Color.new(192, 224, 255)
  7862. end
  7863. #----------------------------------------------------------------------------
  7864. # normal_color
  7865. # Returns the normal color.
  7866. #----------------------------------------------------------------------------
  7867. def normal_color
  7868. return Color.new(255, 255, 255)
  7869. end
  7870. #----------------------------------------------------------------------------
  7871. # disabled_color
  7872. # Returns the disabled color.
  7873. #----------------------------------------------------------------------------
  7874. def disabled_color
  7875. return Color.new(255, 255, 255, 128)
  7876. end
  7877. #----------------------------------------------------------------------------
  7878. # crisis_color
  7879. # Returns the crisis color.
  7880. #----------------------------------------------------------------------------
  7881. def crisis_color
  7882. return Color.new(255, 255, 64)
  7883. end
  7884. #----------------------------------------------------------------------------
  7885. # knockout_color
  7886. # Returns the knockout color.
  7887. #----------------------------------------------------------------------------
  7888. def knockout_color
  7889. return Color.new(255, 64, 0)
  7890. end
  7891. #----------------------------------------------------------------------------
  7892. # vx
  7893. # Returns the x position on the screen.
  7894. #----------------------------------------------------------------------------
  7895. def vx
  7896. return (self.x + (viewport == nil ? 0 : viewport.rect.x))
  7897. end
  7898. #----------------------------------------------------------------------------
  7899. # vy
  7900. # Returns the y position on the screen.
  7901. #----------------------------------------------------------------------------
  7902. def vy
  7903. return (self.y + (viewport == nil ? 0 : viewport.rect.y))
  7904. end
  7905. #----------------------------------------------------------------------------
  7906. # vw
  7907. # Returns the width visible on the screen.
  7908. #----------------------------------------------------------------------------
  7909. def vw
  7910. return (viewport == nil ? self.bitmap.width : viewport.rect.width)
  7911. end
  7912. #----------------------------------------------------------------------------
  7913. # vh
  7914. # Returns the height visible on the screen.
  7915. #----------------------------------------------------------------------------
  7916. def vh
  7917. return (viewport == nil ? self.bitmap.height : viewport.rect.height)
  7918. end
  7919. #----------------------------------------------------------------------------
  7920. # in_screen?
  7921. # Checks if the sprite is visible on the screen.
  7922. #----------------------------------------------------------------------------
  7923. def in_screen?
  7924. return (self.x.between?(0, 639) && (self.y-16).between?(0, 479))
  7925. end
  7926.  
  7927. end
  7928.  
  7929. #==============================================================================
  7930. # RPG::Weapon
  7931. #------------------------------------------------------------------------------
  7932. # This class was enhanced with optional data drawing either in name or in
  7933. # description.
  7934. #==============================================================================
  7935.  
  7936. class RPG::Weapon
  7937.  
  7938. #----------------------------------------------------------------------------
  7939. # name
  7940. # Encapsulation of the name variable to provide the possibility of
  7941. # additional display.
  7942. #----------------------------------------------------------------------------
  7943. def name
  7944. return $BlizzABS.util.add_weapon_text(@name, @id, 1)
  7945. end
  7946. #----------------------------------------------------------------------------
  7947. # description
  7948. # Encapsulation of the description variable to provide the possibility of
  7949. # additional display.
  7950. #----------------------------------------------------------------------------
  7951. def description
  7952. return $BlizzABS.util.add_weapon_text(@description, @id, 2)
  7953. end
  7954.  
  7955. end
  7956.  
  7957. #==============================================================================
  7958. # RPG::Skill
  7959. #------------------------------------------------------------------------------
  7960. # This class was enhanced with optional data drawing either in name or in
  7961. # description.
  7962. #==============================================================================
  7963.  
  7964. class RPG::Skill
  7965.  
  7966. #----------------------------------------------------------------------------
  7967. # name
  7968. # Encapsulation of the name variable to provide the possibility of
  7969. # additional display.
  7970. #----------------------------------------------------------------------------
  7971. def name
  7972. return $BlizzABS.util.add_skill_text(@name, @id, 1)
  7973. end
  7974. #----------------------------------------------------------------------------
  7975. # description
  7976. # Encapsulation of the description variable to provide the possibility of
  7977. # additional display.
  7978. #----------------------------------------------------------------------------
  7979. def description
  7980. return $BlizzABS.util.add_skill_text(@description, @id, 2)
  7981. end
  7982.  
  7983. end
  7984.  
  7985. #==============================================================================
  7986. # RPG::Item
  7987. #------------------------------------------------------------------------------
  7988. # This class was enhanced with optional data drawing either in name or in
  7989. # description.
  7990. #==============================================================================
  7991.  
  7992. class RPG::Item
  7993.  
  7994. #----------------------------------------------------------------------------
  7995. # name
  7996. # Encapsulation of the name variable to provide the possibility of
  7997. # additional display.
  7998. #----------------------------------------------------------------------------
  7999. def name
  8000. return $BlizzABS.util.add_item_text(@name, @id, 1)
  8001. end
  8002. #----------------------------------------------------------------------------
  8003. # description
  8004. # Encapsulation of the description variable to provide the possibility of
  8005. # additional display.
  8006. #----------------------------------------------------------------------------
  8007. def description
  8008. return $BlizzABS.util.add_item_text(@description, @id, 2)
  8009. end
  8010.  
  8011. end
  8012.  
  8013. #==============================================================================
  8014. # Interpreter
  8015. #------------------------------------------------------------------------------
  8016. # This class was enhanced with battleflow controlling commands. It was also
  8017. # enhanced to support pixel movement for the force move command in case the
  8018. # player is affected. It was also enhanced to support Blizz-ABS battle
  8019. # handling and ABSEAL limitation.
  8020. #==============================================================================
  8021.  
  8022. class Interpreter
  8023.  
  8024. # constants to help the user
  8025. PARTY = BlizzABS::PARTY
  8026. TROOP = BlizzABS::TROOP
  8027. INCREASE = BlizzABS::INCREASE
  8028. DECREASE = BlizzABS::DECREASE
  8029. CONSTANT = BlizzABS::CONSTANT
  8030. VARIABLE = BlizzABS::VARIABLE
  8031. KILL = BlizzABS::KILL
  8032. NO_KILL = BlizzABS::NO_KILL
  8033. ADD = BlizzABS::ADD
  8034. REMOVE = BlizzABS::REMOVE
  8035. ATTACK = BlizzABS::ATTACK
  8036. DEFEND = BlizzABS::DEFEND
  8037. ESCAPE = BlizzABS::ESCAPE
  8038. SKILL = BlizzABS::SKILL
  8039. ITEM = BlizzABS::ITEM
  8040. ENEMIES = BlizzABS::ENEMIES
  8041. ACTORS = BlizzABS::ACTORS
  8042. NONE = BlizzABS::NONE
  8043.  
  8044. #----------------------------------------------------------------------------
  8045. # override setup
  8046. #----------------------------------------------------------------------------
  8047. alias setup_blizzabs_later setup
  8048. def setup(list, event_id)
  8049. # call original method
  8050. setup_blizzabs_later(list, event_id)
  8051. # for battleflow control commands
  8052. @SELF = @event_id
  8053. end
  8054. #----------------------------------------------------------------------------
  8055. # override command_end
  8056. #----------------------------------------------------------------------------
  8057. alias cmd_end_blizzabs_later command_end
  8058. def command_end
  8059. # delete event code
  8060. @list = nil
  8061. # call original method if event exists and return result or return true
  8062. return ($game_map.events[@event_id] != nil ? cmd_end_blizzabs_later : true)
  8063. end
  8064. #----------------------------------------------------------------------------
  8065. # override execute_command
  8066. #----------------------------------------------------------------------------
  8067. alias execute_command_blizzabs_later execute_command
  8068. def execute_command
  8069. # if on the map
  8070. if $scene.is_a?(Scene_Map)
  8071. # store old in_battle flag and set to false
  8072. flag, $game_temp.in_battle = $game_temp.in_battle, false
  8073. end
  8074. # call original method
  8075. result = execute_command_blizzabs_later
  8076. # set in_battle flag back if on the map
  8077. $game_temp.in_battle = flag if flag != nil
  8078. # result of the command
  8079. return result
  8080. end
  8081. #----------------------------------------------------------------------------
  8082. # override command_209
  8083. #----------------------------------------------------------------------------
  8084. alias cmd_209_blizzabs_later command_209
  8085. def command_209
  8086. # call original method
  8087. result = cmd_209_blizzabs_later
  8088. # if REPAIR_MOVEMENT is turned on and character is player
  8089. if $game_system.move_fix && @parameters.size == 2 &&
  8090. get_character(@parameters[0]).is_a?(Map_Battler)
  8091. # create command list duplicate
  8092. old_list = @parameters[1].list.clone
  8093. # remove original command list
  8094. @parameters[1].list = []
  8095. # iterate through all commands
  8096. old_list.each {|command|
  8097. # add command to command list
  8098. @parameters[1].list.push(command)
  8099. # if one of the movement commands
  8100. if command.code.between?(1, 13)
  8101. # add pixel movement rate - 1 times to correct movement
  8102. ($BlizzABS.pixel - 1).times{@parameters[1].list.push(command)}
  8103. end}
  8104. @parameters.push(true)
  8105. end
  8106. # return result
  8107. return result
  8108. end
  8109.  
  8110. end
  8111.  
  8112. #==============================================================================
  8113. # Game_Temp
  8114. #------------------------------------------------------------------------------
  8115. # This class was enhanced with a data pack that holds everything needed for
  8116. # the character selection exception handling.
  8117. #==============================================================================
  8118.  
  8119. class Game_Temp
  8120.  
  8121. attr_accessor :select_data
  8122. attr_accessor :hud_refresh
  8123.  
  8124. end
  8125.  
  8126. #==============================================================================
  8127. # Game_System
  8128. #------------------------------------------------------------------------------
  8129. # This class was enhanced with Blizz-ABS system settings, enemy creation and
  8130. # destruction process handling.
  8131. #==============================================================================
  8132.  
  8133. class Game_System
  8134.  
  8135. # setting all accessible variables
  8136. attr_accessor :controls
  8137. attr_accessor :auto_gameover
  8138. attr_accessor :hud
  8139. attr_accessor :hotkeys
  8140. attr_accessor :minimap
  8141. attr_accessor :move_fix
  8142. attr_accessor :_8_way
  8143. attr_accessor :bar_style
  8144. attr_accessor :alignments
  8145. attr_accessor :blizzabs
  8146. attr_accessor :respawn_time
  8147. attr_accessor :attack_button
  8148. attr_accessor :defend_button
  8149. attr_accessor :skill_button
  8150. attr_accessor :item_button
  8151. attr_accessor :select_button
  8152. attr_accessor :hud_button
  8153. attr_accessor :hotkey_button
  8154. attr_accessor :minimap_button
  8155. attr_accessor :turn_button
  8156. attr_accessor :running_button
  8157. attr_accessor :sneaking_button
  8158. attr_accessor :jumping_button
  8159. attr_reader :killed
  8160. attr_reader :caterpillar
  8161. attr_reader :caterpillar_active
  8162. attr_reader :pixel_rate
  8163. attr_reader :bar_opacity
  8164. # compatibility with ccoa's UMS
  8165. attr_accessor :ums_mode
  8166. #----------------------------------------------------------------------------
  8167. # override initiliaze
  8168. #----------------------------------------------------------------------------
  8169. alias init_blizzabs_later initialize
  8170. def initialize
  8171. # call original method
  8172. init_blizzabs_later
  8173. # turn HUD on, Hotkey Assignment Display off and Minimap off
  8174. @hud, @hotkeys, @minimap = true, false, 0
  8175. # set auto gameover
  8176. @auto_gameover = BlizzABS::Config::AUTO_GAMEOVER
  8177. # set movement fix
  8178. @move_fix = BlizzABS::Config::REPAIR_MOVEMENT
  8179. # set 8-way movement
  8180. @_8_way = BlizzABS::Config::EIGHT_WAY_MOVEMENT
  8181. # set respawn time
  8182. @respawn_time = BlizzABS::Config::RESPAWN_TIME
  8183. # all action buttons available
  8184. @attack_button = @defend_button = @skill_button = @item_button =
  8185. @select_button = @hud_button = @hotkey_button = @minimap_button =
  8186. @turn_button = true
  8187. # movement buttons available depending on their configuration
  8188. @running_button = (BlizzABS::Config::RUN_SPEED > 0)
  8189. @sneaking_button = (BlizzABS::Config::SNEAK_SPEED > 0)
  8190. @jumping_button = (BlizzABS::Config::JUMPING > 0)
  8191. # set caterpillar
  8192. @caterpillar = BlizzABS::Config::CATERPILLAR
  8193. # set caterpillar active
  8194. @caterpillar_active = true
  8195. # set pixel movement rate
  8196. self.pixel_rate = BlizzABS::Config::PIXEL_MOVEMENT_RATE
  8197. # set up alignments
  8198. @alignments = {}
  8199. # create all initial alignment group setups
  8200. BlizzABS::Alignments::GROUPS.each {|id|
  8201. @alignments[id] = BlizzABS::AlignmentData.new(id)}
  8202. # reset ABS data
  8203. reset_abs_data
  8204. end
  8205. #----------------------------------------------------------------------------
  8206. # override update
  8207. #----------------------------------------------------------------------------
  8208. alias upd_blizzabs_later update
  8209. def update
  8210. # call original method
  8211. upd_blizzabs_later
  8212. # delete removed alignment groups
  8213. (@alignments.keys - BlizzABS::Alignments::GROUPS).each {|id|
  8214. @alignments.delete(id)}
  8215. # add all new alignment groups
  8216. (BlizzABS::Alignments::GROUPS - @alignments.keys).each {|id|
  8217. @alignments[id] = BlizzABS::AlignmentData.new(id)}
  8218. # update Blizz-ABS Processor
  8219. $BlizzABS.update
  8220. end
  8221. #----------------------------------------------------------------------------
  8222. # caterpillar_active=
  8223. # Sets the caterpillar active mode.
  8224. #----------------------------------------------------------------------------
  8225. def caterpillar_active=(val)
  8226. # dismantle caterpillar if deactivating
  8227. $BlizzABS.actors.each {|actor| actor.remove_from_caterpillar} unless val
  8228. # set new value
  8229. @caterpillar_active = val
  8230. end
  8231. #----------------------------------------------------------------------------
  8232. # caterpillar=
  8233. # Sets the caterpillar value and makes sure that the displayed characters
  8234. # are being refreshed.
  8235. #----------------------------------------------------------------------------
  8236. def caterpillar=(val)
  8237. # if value has changed
  8238. if @caterpillar != val
  8239. # set new value
  8240. @caterpillar = val
  8241. # refresh player
  8242. $game_player.refresh
  8243. end
  8244. end
  8245. #----------------------------------------------------------------------------
  8246. # pixel_rate=
  8247. # val - new pixel movement rate
  8248. # Changes the pixel movement rate is necessary.
  8249. #----------------------------------------------------------------------------
  8250. def pixel_rate=(val)
  8251. if val > 5
  8252. @pixel_rate = 5
  8253. elsif val < 0
  8254. @pixel_rate = 0
  8255. else
  8256. @pixel_rate = val
  8257. end
  8258. end
  8259. #----------------------------------------------------------------------------
  8260. # add_battlers_number
  8261. # group - group of the battler
  8262. # val - the value to add
  8263. # Adds a count to the battler group count.
  8264. #----------------------------------------------------------------------------
  8265. def add_battler_number(group, val)
  8266. @battlers_number[group] = battlers_number_group(group) + val
  8267. @battlers_number[group] = 0 if @battlers_number[group] < 0
  8268. end
  8269. #----------------------------------------------------------------------------
  8270. # battlers_number
  8271. # Returns the number of battlers on the current map.
  8272. #----------------------------------------------------------------------------
  8273. def battlers_number
  8274. return @battlers_number.sum
  8275. end
  8276. #----------------------------------------------------------------------------
  8277. # battlers_number_group
  8278. # group - group of the battler
  8279. # Returns the number of battlers on the current map from a specific type.
  8280. #----------------------------------------------------------------------------
  8281. def battlers_number_group(group)
  8282. return (@battlers_number[group] != nil ? @battlers_number[group] : 0)
  8283. end
  8284. #----------------------------------------------------------------------------
  8285. # reset_abs_data
  8286. # Resets ABS map data.
  8287. #----------------------------------------------------------------------------
  8288. def reset_abs_data
  8289. # reset killed battlers arrays and the counters
  8290. @killed, @battlers_number = {}, {}
  8291. end
  8292.  
  8293. end
  8294.  
  8295. #==============================================================================
  8296. # Game_Screen
  8297. #------------------------------------------------------------------------------
  8298. # This class was modified to correctly update pictures.
  8299. #==============================================================================
  8300.  
  8301. class Game_Screen
  8302.  
  8303. #--------------------------------------------------------------------------
  8304. # override update
  8305. #--------------------------------------------------------------------------
  8306. alias upd_blizzabs_later update
  8307. def update
  8308. # if on the map
  8309. if $scene.is_a?(Scene_Map)
  8310. # store old in_battle flag and set to false
  8311. flag, $game_temp.in_battle = $game_temp.in_battle, false
  8312. end
  8313. # call original method
  8314. upd_blizzabs_later
  8315. # set in_battle flag back if on the map
  8316. $game_temp.in_battle = flag if $scene.is_a?(Scene_Map)
  8317. end
  8318.  
  8319. end
  8320.  
  8321. #==============================================================================
  8322. # Game_BattleAction
  8323. #------------------------------------------------------------------------------
  8324. # This class was modified to prevent a bug where deciding a random target
  8325. # for an enemy would cause the action to be cleared.
  8326. #==============================================================================
  8327.  
  8328. class Game_BattleAction
  8329.  
  8330. #--------------------------------------------------------------------------
  8331. # decide_random_target_for_enemy
  8332. # Dummy method.
  8333. #--------------------------------------------------------------------------
  8334. def decide_random_target_for_enemy
  8335. end
  8336.  
  8337. end
  8338.  
  8339. #==============================================================================
  8340. # Game_Battler
  8341. #------------------------------------------------------------------------------
  8342. # This class was enhanced with helping variables and methods.
  8343. #==============================================================================
  8344.  
  8345. class Game_Battler
  8346.  
  8347. # setting all accessible variables
  8348. attr_accessor :group
  8349. attr_accessor :state_time
  8350. attr_writer :hpdamage
  8351. attr_writer :spdamage
  8352. attr_accessor :last_attackers
  8353. attr_accessor :last_slip_attackers
  8354. attr_accessor :last_action
  8355. attr_accessor :last_targets
  8356. attr_accessor :last_hit_by
  8357.  
  8358. #----------------------------------------------------------------------------
  8359. # initialize
  8360. #----------------------------------------------------------------------------
  8361. alias initialize_blizzabs_earlier initialize
  8362. def initialize
  8363. initialize_blizzabs_earlier
  8364. # reset last attackers
  8365. @last_attackers = []
  8366. # reset last slip attackers
  8367. @last_slip_attackers = []
  8368. # reset last action
  8369. @last_action = ["none", false]
  8370. # reset last targets
  8371. @last_targets = []
  8372. # reset lats hit by
  8373. @last_hit_by = nil
  8374. end
  8375. #----------------------------------------------------------------------------
  8376. # override hp=
  8377. #----------------------------------------------------------------------------
  8378. alias hp_is_blizzabs_later hp=
  8379. def hp=(val)
  8380. # store difference
  8381. @hpdamage = @hp-val
  8382. # call original method
  8383. hp_is_blizzabs_later(val)
  8384. end
  8385. #----------------------------------------------------------------------------
  8386. # override sp=
  8387. #----------------------------------------------------------------------------
  8388. alias sp_is_blizzabs_later sp=
  8389. def sp=(val)
  8390. # store difference
  8391. @spdamage = @sp-val
  8392. # call original method
  8393. sp_is_blizzabs_later(val)
  8394. end
  8395. #----------------------------------------------------------------------------
  8396. # hpdamage
  8397. # Returns hpdamage encapsulated.
  8398. #----------------------------------------------------------------------------
  8399. def hpdamage
  8400. return (@hpdamage == nil ? 0 : @hpdamage)
  8401. end
  8402. #----------------------------------------------------------------------------
  8403. # spdamage
  8404. # Returns spdamage encapsulated.
  8405. #----------------------------------------------------------------------------
  8406. def spdamage
  8407. return (@spdamage == nil ? 0 : @spdamage)
  8408. end
  8409.  
  8410. end
  8411.  
  8412. #==============================================================================
  8413. # Game_Actor
  8414. #------------------------------------------------------------------------------
  8415. # This class was enhanced with helping variables and methods.
  8416. #==============================================================================
  8417.  
  8418. class Game_Actor
  8419.  
  8420. # setting all accessible variables
  8421. attr_accessor :skill
  8422. attr_accessor :item
  8423. attr_accessor :offensive
  8424. attr_accessor :aggressive
  8425. attr_reader :skill_hotkeys
  8426. attr_reader :item_hotkeys
  8427. attr_reader :force_offensive
  8428. attr_reader :force_aggressive
  8429. attr_reader :triggers
  8430. #----------------------------------------------------------------------------
  8431. # override setup
  8432. #----------------------------------------------------------------------------
  8433. alias setup_blizzabs_later setup
  8434. def setup(id)
  8435. # call original method
  8436. setup_blizzabs_later(id)
  8437. # skill and item IDs on hotkeys
  8438. @skill, @item = 0, 0
  8439. # skills -> skill ID on key index
  8440. @skill_hotkeys = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  8441. # items -> item ID on key index
  8442. @item_hotkeys = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  8443. # last known level
  8444. @old_level = @level
  8445. # normal AI setup attributes
  8446. @offensive, @aggressive, @force_offensive, @force_aggressive = 8, 8, 0, 0
  8447. # hash for state time
  8448. @state_time = {}
  8449. # trigger AI conditions
  8450. @triggers = []
  8451. end
  8452. #----------------------------------------------------------------------------
  8453. # force_offensive=
  8454. # Encapsulation method that corrects the offensive attribute's value.
  8455. #----------------------------------------------------------------------------
  8456. def force_offensive=(val)
  8457. if val > 15
  8458. @force_offensive = 15
  8459. elsif val < 0
  8460. @force_offensive = 0
  8461. else
  8462. @force_offensive = val
  8463. end
  8464. end
  8465. #----------------------------------------------------------------------------
  8466. # force_aggressive=
  8467. # Encapsulation method that corrects the aggressive attribute's value.
  8468. #----------------------------------------------------------------------------
  8469. def force_aggressive=(val)
  8470. if val > 15
  8471. @force_aggressive = 15
  8472. elsif val < 0
  8473. @force_aggressive = 0
  8474. else
  8475. @force_aggressive = val
  8476. end
  8477. end
  8478. #----------------------------------------------------------------------------
  8479. # now_exp
  8480. # Returns the current EXP as number.
  8481. #----------------------------------------------------------------------------
  8482. def now_exp
  8483. return (@exp - @exp_list[@level])
  8484. end
  8485. #----------------------------------------------------------------------------
  8486. # next_exp
  8487. # Returns the EXP needed to level up or 0 is there are no more levels.
  8488. #----------------------------------------------------------------------------
  8489. def next_exp
  8490. return (@exp_list[@level+1] > 0 ? @exp_list[@level+1]-@exp_list[@level] : 0)
  8491. end
  8492. #----------------------------------------------------------------------------
  8493. # full_next_exp
  8494. # Returns the EXP needed to reach the next level.
  8495. #----------------------------------------------------------------------------
  8496. def full_next_exp
  8497. return (@exp_list[@level+1] > 0 ? @exp_list[@level+1] : 0)
  8498. end
  8499. #----------------------------------------------------------------------------
  8500. # level_up?
  8501. # Compares current level to lastly known level and returns a level up.
  8502. #----------------------------------------------------------------------------
  8503. def level_up?
  8504. # result of level up and set current level is now last known level
  8505. result, @old_level = (@old_level < @level), @level
  8506. # return result
  8507. return result
  8508. end
  8509.  
  8510. end
  8511.  
  8512. #==============================================================================
  8513. # Game_Enemy
  8514. #------------------------------------------------------------------------------
  8515. # This class was enhanced with helping variables.
  8516. #==============================================================================
  8517.  
  8518. class Game_Enemy
  8519.  
  8520. # setting all accessible variables
  8521. attr_writer :enemy_id
  8522. #----------------------------------------------------------------------------
  8523. # Override Initialization
  8524. # enemy - enemy in the database
  8525. #----------------------------------------------------------------------------
  8526. alias init_blizzabs_later initialize
  8527. def initialize(enemy, other = nil)
  8528. # if Blizz-ABS enemy initialization
  8529. if other == nil
  8530. # call superclass method
  8531. super()
  8532. # the enemy ID, no troop and not member in troop
  8533. @enemy_id, @troop_id, @member_index = enemy.id, 0, 0
  8534. # battler spriteset name and spriteset hue
  8535. @battler_name, @battler_hue = enemy.battler_name, enemy.battler_hue
  8536. # current HP and SP
  8537. @hp, @sp = maxhp, maxsp
  8538. # not hidden and not immortal
  8539. @hidden = @immortal = false
  8540. else
  8541. # call normal enemy initialization
  8542. init_blizzabs_later(enemy, other)
  8543. end
  8544. # hash for state time
  8545. @state_time = {}
  8546. end
  8547.  
  8548. end
  8549.  
  8550. #==============================================================================
  8551. # Game_Map
  8552. #------------------------------------------------------------------------------
  8553. # This class was redefined by large parts for pixel movement handling and
  8554. # quick minimap passability access.
  8555. #==============================================================================
  8556.  
  8557. class Game_Map
  8558.  
  8559. # setting all accessible variables
  8560. attr_reader :virtual_passability
  8561. attr_reader :map
  8562. attr_reader :respawns
  8563. #----------------------------------------------------------------------------
  8564. # override setup
  8565. #----------------------------------------------------------------------------
  8566. alias setup_blizzabs_later setup
  8567. def setup(map_id)
  8568. # array of Respawn Points
  8569. @respawns = []
  8570. # call original method
  8571. setup_blizzabs_later(map_id)
  8572. # setup enemies on the map
  8573. $BlizzABS.battlers_refresh
  8574. # if using the intelligent minimap system
  8575. if BlizzABS::Config::INTELLIGENT_PASSABILITY
  8576. # load virtual passability map from file
  8577. @virtual_passability = load_data('Data/Map_Data.abs')[0][map_id]
  8578. else
  8579. # create virtual passability map
  8580. @virtual_passability = $BlizzABS.util.setup_passability(@map)
  8581. end
  8582. # reset remotes, damage and beam sprites and clear observation data
  8583. $BlizzABS.cache.clean
  8584. end
  8585. #----------------------------------------------------------------------------
  8586. # events_only
  8587. # Returns an array of events that have no battler.
  8588. #----------------------------------------------------------------------------
  8589. def events_only
  8590. return (@events.values - self.battlers)
  8591. end
  8592. #----------------------------------------------------------------------------
  8593. # battlers
  8594. # Returns an array of all map battlers.
  8595. #----------------------------------------------------------------------------
  8596. def battlers
  8597. return (@events.values.find_all {|e| e.is_a?(Map_Battler)})
  8598. end
  8599. #----------------------------------------------------------------------------
  8600. # battlers_group
  8601. # group - alignment group of the battler
  8602. # Returns an array of map battlers from a specific alignment group.
  8603. #----------------------------------------------------------------------------
  8604. def battlers_group(group)
  8605. return (battlers.find_all {|battler| battler.ai.group == group})
  8606. end
  8607. #----------------------------------------------------------------------------
  8608. # battlers_in_range
  8609. # Checks how many battler instances are within ABSEAL range.
  8610. #----------------------------------------------------------------------------
  8611. def battlers_in_range
  8612. return (battlers.find_all {|battler| battler.valid? && battler.update?})
  8613. end
  8614. #----------------------------------------------------------------------------
  8615. # rename_event
  8616. # id - event ID
  8617. # name - new name for the event
  8618. # Allows the renaming of specific events and applies Blizz-ABS update
  8619. # handling.
  8620. #----------------------------------------------------------------------------
  8621. def rename_event(id, name)
  8622. # stop if event doesn't exist
  8623. return if @events[id] == nil
  8624. # set new name
  8625. self.map.events[id].name = name
  8626. # store old event
  8627. character = @events[id]
  8628. # update event by using name
  8629. $BlizzABS.check_event_name(id)
  8630. # clone position of the old character
  8631. @events[id].clone_position(character)
  8632. # stop if scene not Scene_Map or spriteset doesn't exist
  8633. return if !$scene.is_a?(Scene_Map) || $scene.spriteset == nil
  8634. # find this event's sprite
  8635. $scene.spriteset.character_sprites.each {|sprite|
  8636. # if sprite found
  8637. if sprite.character == character
  8638. # dispose old sprites
  8639. sprite.dispose
  8640. # set new character
  8641. sprite.character = @events[id]
  8642. # update sprite
  8643. sprite.update
  8644. # event found, stop here
  8645. break
  8646. end}
  8647. end
  8648. #----------------------------------------------------------------------------
  8649. # self_valid?
  8650. # x - x-coordinate
  8651. # y - y-coordinate
  8652. # Checks if coordinates are valid. (pixel movement)
  8653. #----------------------------------------------------------------------------
  8654. def self_valid?(x, y)
  8655. # get pixel movement rate
  8656. pix = $BlizzABS.pixel
  8657. # checks if coordinates are valid
  8658. return (x >= 0 && x < width * pix - pix + 1 && y >= 0 && y < height * pix - pix + 1)
  8659. end
  8660. #----------------------------------------------------------------------------
  8661. # direction_valid?
  8662. # x - x-coordinate
  8663. # y - y-coordinate
  8664. # Checks if coordinates are valid. (pixel movement)
  8665. #----------------------------------------------------------------------------
  8666. def direction_valid?(x, y)
  8667. # get pixel movement rate
  8668. pix = $BlizzABS.pixel
  8669. # checks if coordinates are valid
  8670. return (x >= 0 && x < width * pix && y >= 0 && y < height * pix)
  8671. end
  8672. #----------------------------------------------------------------------------
  8673. # self_passable?
  8674. # x - x-coordinate
  8675. # y - y-coordinate
  8676. # d - direction
  8677. # self_event - self event
  8678. # Checks if passable. (pixel movement)
  8679. #----------------------------------------------------------------------------
  8680. def self_passable?(x, y, d, self_event)
  8681. # get pixel movement rate and set bit
  8682. pix, bit = $BlizzABS.pixel, (1 << (d / 2 - 1)) & 0x0F
  8683. # if not in horizontal center of 32x32 pixel tile
  8684. if x != x / pix * pix
  8685. # if current two tiles are impassable from one to another
  8686. unless direction_passable?(x / pix * pix, y, 6) &&
  8687. direction_passable?((x + pix) / pix * pix, y, 4)
  8688. # impassable
  8689. return false
  8690. end
  8691. end
  8692. # if not in vertical center of 32x32 pixel tile
  8693. if y != y / pix * pix
  8694. # if current two tiles are impassable from one to another
  8695. unless direction_passable?(x, y / pix * pix, 2) &&
  8696. direction_passable?(x, (y + pix) / pix * pix, 8)
  8697. # impassable
  8698. return false
  8699. end
  8700. end
  8701. # if jumping
  8702. if d == 0
  8703. # return passability on forced jump location or in any direction
  8704. return (BlizzABS::Config::ALLOW_JUMP_TAGS.include?(
  8705. $game_map.terrain_tag(x / pix, y / pix)) ||
  8706. direction_passable?(x, y + pix - 1, 2) ||
  8707. direction_passable?(x, y, 4) ||
  8708. direction_passable?(x + pix - 1, y, 6) ||
  8709. direction_passable?(x, y, 8))
  8710. end
  8711. # if changing tile and either no tile or no event exception
  8712. if changing_tiles(x, y, d) && (!tile_exception(x, y, d) ||
  8713. !event_exception(x, y, d, bit))
  8714. # impassable
  8715. return false
  8716. end
  8717. # iterate through all corners
  8718. (0...4).each {|i|
  8719. # gets coordinates to check
  8720. xr, yr = x + (pix - 1) * (i % 2), y + (pix - 1) * (i / 2)
  8721. # unless checking event and checking tile
  8722. unless event_check(xr, yr, d, self_event) && tile_check(xr, yr, d)
  8723. # impassable
  8724. return false
  8725. end}
  8726. # passable
  8727. return true
  8728. end
  8729. #----------------------------------------------------------------------------
  8730. # direction_passable?
  8731. # x - x-coordinate
  8732. # y - y-coordinate
  8733. # d - direction
  8734. # self_event - self event
  8735. # Checks if passable. (pixel movement)
  8736. #----------------------------------------------------------------------------
  8737. def direction_passable?(x, y, d)
  8738. # impassable if coordinates not valid
  8739. return false unless direction_valid?(x, y)
  8740. # return event check and tile check result
  8741. return (event_check(x, y, d) && tile_check(x, y, d))
  8742. end
  8743. #----------------------------------------------------------------------------
  8744. # event_check
  8745. # x - x-coordinate
  8746. # y - y-coordinate
  8747. # d - direction
  8748. # self_event - self event
  8749. # Checks if passable events. (pixel movement)
  8750. #----------------------------------------------------------------------------
  8751. def event_check(x, y, d, self_event = nil)
  8752. # get pixel movement rate and set bit
  8753. pix, bit = $BlizzABS.pixel, (1 << (d / 2 - 1)) & 0x0F
  8754. # iterate trough all events except self
  8755. (self.events_only - [self_event]).each {|event|
  8756. # if there's an event that's not through and has a graphic
  8757. if event.character_name != "" &&
  8758. $BlizzABS.util.intersection(Rect.new(x, y,
  8759. 1, 1), event.phitbox) && !event.through &&
  8760. (!self_event.is_a?(Map_Battler) || event.tile_id >= 384)
  8761. # if obstacle bit is set
  8762. if @passages[event.tile_id] & bit != 0
  8763. # get x and y of next tile
  8764. case d
  8765. when 2 then nx, ny = x / pix, (y + 1) / pix
  8766. when 4 then nx, ny = (x - 1) / pix, y / pix
  8767. when 6 then nx, ny = (x + 1) / pix, y / pix
  8768. when 8 then nx, ny = x / pix, (y - 1) / pix
  8769. else
  8770. nx = ny = nil
  8771. end
  8772. # impassable if not on the same tile anymore
  8773. return false if x / pix != nx || y / pix != ny
  8774. # if obstacle bit is set in all directions
  8775. elsif @passages[event.tile_id] & 0x0F == 0x0F
  8776. # impassable in the given direction
  8777. return false
  8778. # if priority is 0
  8779. elsif @priorities[event.tile_id] == 0
  8780. # passable in the given direction
  8781. return true
  8782. # if event is not a tile and not through
  8783. elsif !event.through
  8784. # impassable in any direction
  8785. return false
  8786. end
  8787. end}
  8788. # passable
  8789. return true
  8790. end
  8791. #----------------------------------------------------------------------------
  8792. # tile_check
  8793. # x - x-coordinate
  8794. # y - y-coordinate
  8795. # d - direction
  8796. # Checks if passable tile. (pixel movement)
  8797. #----------------------------------------------------------------------------
  8798. def tile_check(x, y, d)
  8799. # get pixel movement rate and set bit
  8800. pix, bit = $BlizzABS.pixel, (1 << (d / 2 - 1)) & 0x0F
  8801. # passable if virtual passability works
  8802. return true if ($game_map.virtual_passability[x / pix, y / pix] & bit != 0x00)
  8803. # get x and y of next tile
  8804. case d
  8805. when 2 then nx, ny = x / pix, (y + 1) / pix
  8806. when 4 then nx, ny = (x - 1) / pix, y / pix
  8807. when 6 then nx, ny = (x + 1) / pix, y / pix
  8808. when 8 then nx, ny = x / pix, (y - 1) / pix
  8809. else
  8810. nx = ny = nil
  8811. end
  8812. # passable if still on the same tile
  8813. return (x / pix == nx && y / pix == ny)
  8814. end
  8815. #----------------------------------------------------------------------------
  8816. # event_exception
  8817. # x - x-coordinate
  8818. # y - y-coordinate
  8819. # d - direction
  8820. # bit - passability attributes
  8821. # Checks if passable events. (pixel movement)
  8822. #----------------------------------------------------------------------------
  8823. def event_exception(x, y, d, bit)
  8824. # get pixel movement rate
  8825. pix = $BlizzABS.pixel
  8826. # iterate trough all events
  8827. self.events_only.each {|event|
  8828. # if there's an event that's a tile and not through
  8829. if !event.through && event.tile_id >= 384
  8830. # get data depending on direction
  8831. case d
  8832. when 2
  8833. x1, y1, bit1 = x / pix, (y + pix) / pix, 0x04
  8834. x2, y2, bit2 = (x + pix) / pix, y1, 0x02
  8835. when 4
  8836. x1, y1, bit1 = (x - pix) / pix, y / pix, 0x01
  8837. x2, y2, bit2 = x1, (y + pix) / pix, 0x08
  8838. when 6
  8839. x1, y1, bit1 = (x + pix) / pix, y / pix, 0x01
  8840. x2, y2, bit2 = x1, (y + pix) / pix, 0x08
  8841. when 8
  8842. x1, y1, bit1 = x / pix, (y - pix) / pix, 0x04
  8843. x2, y2, bit2 = (x + pix) / pix, y1, 0x02
  8844. end
  8845. # temporary variable
  8846. passage = @passages[event.tile_id]
  8847. # if tile is at right position and impassable
  8848. if event.x == x1 && event.y == y1 && passage & bit1 == bit1 ||
  8849. event.x == x2 && event.y == y2 && passage & bit2 == bit2
  8850. # impassable
  8851. return false
  8852. end
  8853. end}
  8854. # passable
  8855. return true
  8856. end
  8857. #----------------------------------------------------------------------------
  8858. # tile_exception
  8859. # x - x-coordinate
  8860. # y - y-coordinate
  8861. # d - direction
  8862. # Checks if passable when changing tiles. (pixel movement)
  8863. #----------------------------------------------------------------------------
  8864. def tile_exception(x, y, d)
  8865. # get pixel movement rate
  8866. pix = $BlizzABS.pixel
  8867. # check direction and return map passability depending on direction
  8868. return case d
  8869. when 2
  8870. (($game_map.virtual_passability[x / pix, (y + pix) / pix] & 0x04 == 0x04) &&
  8871. ($game_map.virtual_passability[(x + pix) / pix, (y + pix) / pix] & 0x02 == 0x02))
  8872. when 4
  8873. (($game_map.virtual_passability[(x - pix) / pix, y / pix] & 0x01 == 0x01) &&
  8874. ($game_map.virtual_passability[(x - pix) / pix, (y + pix) / pix] & 0x08 == 0x08))
  8875. when 6
  8876. (($game_map.virtual_passability[(x + pix) / pix, y / pix] & 0x01 == 0x01) &&
  8877. ($game_map.virtual_passability[(x + pix) / pix, (y + pix) / pix] & 0x08 == 0x08))
  8878. when 8
  8879. (($game_map.virtual_passability[x / pix, (y - pix) / pix] & 0x04 == 0x04) &&
  8880. ($game_map.virtual_passability[(x + pix) / pix, (y - pix) / pix] & 0x02 == 0x02))
  8881. end
  8882. end
  8883. #----------------------------------------------------------------------------
  8884. # changing_tiles
  8885. # x - x-coordinate
  8886. # y - y-coordinate
  8887. # d - direction
  8888. # Checks if changing tiles. (pixel movement)
  8889. #----------------------------------------------------------------------------
  8890. def changing_tiles(x, y, d)
  8891. # get pixel movement rate
  8892. pix = $BlizzABS.pixel
  8893. # if not changing the tile (up/down)
  8894. if (y / pix != (y + pix - 1) / pix || x / pix == (x + pix - 1) / pix) &&
  8895. (d == 2 || d == 8)
  8896. # not changing
  8897. return false
  8898. end
  8899. # if not changing the tile (left/right)
  8900. if (x / pix != (x + pix - 1) / pix || y / pix == (y + pix - 1) / pix) &&
  8901. (d == 4 || d == 6)
  8902. # not changing
  8903. return false
  8904. end
  8905. # changing
  8906. return true
  8907. end
  8908. #----------------------------------------------------------------------------
  8909. # pixel_counter?
  8910. # x - x-coordinate
  8911. # y - y-coordinate
  8912. # Checks if counter. (pixel movement)
  8913. #----------------------------------------------------------------------------
  8914. def pixel_counter?(x, y)
  8915. # no counter if map ID is invalid
  8916. return false if @map_id == 0
  8917. # get pixel movement rate and initialize result
  8918. pix, result = $BlizzABS.pixel, false
  8919. # iterate through all layers and check each modified tile (pixel movement)
  8920. BlizzABS::Cache::MapLayers.each {|i| (0...pix).each {|j| (0...pix).each {|k|
  8921. # if tile is not valid ID
  8922. if data[(x+j)/pix, (y+k)/pix, i] == nil
  8923. # no counter
  8924. return false
  8925. # if counter bit is set
  8926. elsif @passages[data[(x+j)/pix, (y+k)/pix, i]] & 0x80 == 0x80
  8927. # counter
  8928. result = true
  8929. else
  8930. # no counter
  8931. return false
  8932. end}}
  8933. # return the result
  8934. return result}
  8935. # no counter
  8936. return false
  8937. end
  8938. #----------------------------------------------------------------------------
  8939. # pixel_bush?
  8940. # x - x-coordinate
  8941. # y - y-coordinate
  8942. # Checks if bush. (pixel movement)
  8943. #----------------------------------------------------------------------------
  8944. def pixel_bush?(x, y)
  8945. # no bush if map ID is invalid
  8946. return false if @map_id == 0
  8947. # get pixel movement rate
  8948. pix = $BlizzABS.pixel
  8949. # iterate through all layers
  8950. BlizzABS::Cache::MapLayers.each {|i|
  8951. # if tile ID not valid
  8952. if data[(x+pix/2)/pix, (y+pix/2)/pix, i] == nil
  8953. # no bush
  8954. return false
  8955. # if bush bit is set
  8956. elsif @passages[data[(x+pix/2)/pix, (y+pix/2)/pix, i]] & 0x40 == 0x40
  8957. # bush
  8958. return true
  8959. end}
  8960. # no bush
  8961. return false
  8962. end
  8963. #----------------------------------------------------------------------------
  8964. # jump_passable?
  8965. # x - x-coordinate
  8966. # y - y-coordinate
  8967. # nx - new x-coordinate
  8968. # ny - new y-coordinate
  8969. # Checks if there is a tile with NO_JUMP_TAGS or WALL_TAGS tag, so jumping
  8970. # isn't possible.
  8971. #----------------------------------------------------------------------------
  8972. def jump_passable?(x, y, nx, ny)
  8973. # passable if tags are not being used at all (to save process time)
  8974. return true if BlizzABS::Config::NO_JUMP_TAGS.size == 0
  8975. # get pixel movement rate
  8976. pix = $BlizzABS.pixel
  8977. # get jump direction
  8978. xdir, ydir = (nx - x).sgn, (ny - y).sgn
  8979. # iterate
  8980. loop do
  8981. # if tile has one of the terrain tags or event that can't be jumped
  8982. if !event_jump_passable?(x, y) ||
  8983. BlizzABS::Config::NO_JUMP_TAGS.include?(terrain_tag(x / pix, y / pix))
  8984. # impassable
  8985. return false
  8986. # if all tiles are passable
  8987. elsif x == nx && y == ny
  8988. # passable
  8989. return true
  8990. end
  8991. # next tile
  8992. x += xdir * pix
  8993. y += ydir * pix
  8994. end
  8995. end
  8996. #----------------------------------------------------------------------------
  8997. # event_passable?
  8998. # x - x-coordinate
  8999. # y - y-coordinate
  9000. # Checks if the given tile is passable in any direction right now.
  9001. #----------------------------------------------------------------------------
  9002. def event_passable?(x, y)
  9003. # get pixel movement rate
  9004. pix = $BlizzABS.pixel
  9005. # iterate trough all events
  9006. self.events_only.each {|event|
  9007. # if there's an event that's no enemy/actor/dropped item and not through
  9008. if event.tile_id >= 0 && event.x == x / pix && event.y == y / pix &&
  9009. !event.through
  9010. # if obstacle bit is set
  9011. if @passages[event.tile_id] & 0x0F == 0x0F
  9012. # impassable tile in the given direction
  9013. return false
  9014. # if priority is 0
  9015. elsif @priorities[event.tile_id] == 0
  9016. # passable in the given direction
  9017. return true
  9018. end
  9019. end}
  9020. # passable
  9021. return true
  9022. end
  9023. #----------------------------------------------------------------------------
  9024. # event_jump_passable?
  9025. # x - x-coordinate
  9026. # y - y-coordinate
  9027. # Checks if the given tile is passable by jumping due to events.
  9028. #----------------------------------------------------------------------------
  9029. def event_jump_passable?(x, y)
  9030. # get pixel movement rate
  9031. pix = $BlizzABS.pixel
  9032. # iterate trough all events
  9033. self.events_only.each {|event|
  9034. # if there's an event that is not enemy/actor/dropped and not jumpable
  9035. if event.tile_id >= 0 && $BlizzABS.util.intersection(Rect.new(x, y,
  9036. 1, 1), event.phitbox) && event.no_jump
  9037. return false
  9038. end}
  9039. # iterate through battlers
  9040. self.battlers.each {|battler|
  9041. # if there's a battler that is not jumpable
  9042. if $BlizzABS.util.intersection(Rect.new(x, y, 1, 1),
  9043. battler.phitbox) && battler.no_jump
  9044. return false
  9045. end}
  9046. # passable
  9047. return true
  9048. end
  9049.  
  9050. end
  9051.  
  9052. #==============================================================================
  9053. # Game_Party
  9054. #------------------------------------------------------------------------------
  9055. # This class was redefined to create characters used by the caterpillar and to
  9056. # delete all remotes when a saved game was loaded.
  9057. #==============================================================================
  9058.  
  9059. class Game_Party
  9060.  
  9061. #----------------------------------------------------------------------------
  9062. # override setup_starting_members
  9063. #----------------------------------------------------------------------------
  9064. alias setup_starting_members_blizzabs_later setup_starting_members
  9065. def setup_starting_members
  9066. # call original method
  9067. setup_starting_members_blizzabs_later
  9068. # initialize caterpillar
  9069. $BlizzABS.init_caterpillar
  9070. end
  9071. #----------------------------------------------------------------------------
  9072. # override refresh
  9073. #----------------------------------------------------------------------------
  9074. alias refresh_blizzabs_later refresh
  9075. def refresh
  9076. # call original method
  9077. refresh_blizzabs_later
  9078. # reset remotes and damage sprites
  9079. $BlizzABS.cache.clean
  9080. # reinitialize caterpillar
  9081. $BlizzABS.init_caterpillar
  9082. end
  9083.  
  9084. end
  9085.  
  9086. #==============================================================================
  9087. # Game_Character
  9088. #------------------------------------------------------------------------------
  9089. # This class was redefined to support name event command input, looping
  9090. # animations, ABSEAL update limitation and relational movement commands.
  9091. #==============================================================================
  9092.  
  9093. class Game_Character
  9094.  
  9095. # constants to help the user
  9096. PARTY = BlizzABS::PARTY
  9097. TROOP = BlizzABS::TROOP
  9098. INCREASE = BlizzABS::INCREASE
  9099. DECREASE = BlizzABS::DECREASE
  9100. CONSTANT = BlizzABS::CONSTANT
  9101. VARIABLE = BlizzABS::VARIABLE
  9102. KILL = BlizzABS::KILL
  9103. NO_KILL = BlizzABS::NO_KILL
  9104. ADD = BlizzABS::ADD
  9105. REMOVE = BlizzABS::REMOVE
  9106. ATTACK = BlizzABS::ATTACK
  9107. DEFEND = BlizzABS::DEFEND
  9108. ESCAPE = BlizzABS::ESCAPE
  9109. SKILL = BlizzABS::SKILL
  9110. ITEM = BlizzABS::ITEM
  9111. ENEMIES = BlizzABS::ENEMIES
  9112. ACTORS = BlizzABS::ACTORS
  9113. NONE = BlizzABS::NONE
  9114. # setting all accessible variables
  9115. attr_accessor :erased
  9116. attr_accessor :loop_animation_id
  9117. attr_accessor :terminate
  9118. attr_accessor :teleport
  9119. attr_accessor :icondrop
  9120. attr_accessor :no_jump
  9121. attr_accessor :center_sprite
  9122. attr_accessor :hitbox_width
  9123. attr_accessor :hitbox_height
  9124. attr_accessor :no_dmg_sprites
  9125. attr_reader :move_route
  9126. attr_reader :move_type
  9127. attr_reader :pattern_size
  9128. #----------------------------------------------------------------------------
  9129. # override initialize
  9130. #----------------------------------------------------------------------------
  9131. alias init_blizzabs_later initialize
  9132. def initialize
  9133. # call original method
  9134. init_blizzabs_later
  9135. # set loop animation
  9136. @loop_animation_id = 0
  9137. # default number of frames on a spriteset
  9138. @pattern_size = 4
  9139. # last moving flag
  9140. @last_moving = false
  9141. # no jump flag
  9142. @no_jump = false
  9143. # center sprite flag
  9144. @center_sprite = false
  9145. # hitbox size
  9146. @hitbox_width = @hitbox_height = 32
  9147. # no damage sprites
  9148. @no_dmg_sprites = false
  9149. end
  9150. #----------------------------------------------------------------------------
  9151. # update?
  9152. # Checks whether the character should be updated or not.
  9153. #----------------------------------------------------------------------------
  9154. def update?
  9155. # if this map has ABSEAL disabled or it's the player or an actor
  9156. if BlizzABS::Config::DISABLE_ANTILAG_IDS.include?($game_map.map_id)
  9157. # update
  9158. return true
  9159. end
  9160. # if auto-start or parallel process or excluded from ABSEAL
  9161. if @trigger == 3 || @trigger == 4 || self.name.clone.gsub!('\\eal') {''}
  9162. # update
  9163. return true
  9164. end
  9165. # if autokiller is on and no character sprite and no tile sprite
  9166. if BlizzABS::Config::ABSEAL_AUTOKILL && @character_name == '' &&
  9167. @tile_id < 384 && !@teleport
  9168. # don't update
  9169. return false
  9170. end
  9171. # check ABSEAL range
  9172. return in_abseal_range?
  9173. end
  9174. #----------------------------------------------------------------------------
  9175. # in_abseal_range?
  9176. # Checks if the character is within ABSEAL range.
  9177. #----------------------------------------------------------------------------
  9178. def in_abseal_range?
  9179. # correct value out of range for ABSEAL factor
  9180. factor = BlizzABS::Config::ABSEAL_FACTOR < 1 ? 1 :
  9181. BlizzABS::Config::ABSEAL_FACTOR.to_i
  9182. # don't update if outside of screen (left, up, right, down)
  9183. return false if @real_x < $game_map.display_x - factor * 128
  9184. return false if @real_y < $game_map.display_y - factor * 128
  9185. return false if @real_x >= $game_map.display_x + 2560 + factor * 128
  9186. return false if @real_y >= $game_map.display_y + 1920 + factor * 128
  9187. # update
  9188. return true
  9189. end
  9190. #----------------------------------------------------------------------------
  9191. # clone_position
  9192. # character - the other character
  9193. # Sets own position to that of the other character with correction of pixel
  9194. # movement.
  9195. #----------------------------------------------------------------------------
  9196. def clone_position(character)
  9197. # copy real_x and real_y
  9198. @real_x, @real_y = character.real_x, character.real_y
  9199. # get pixel movement rate
  9200. pix = $BlizzABS.pixel
  9201. # if battler and not battler before
  9202. if self.is_a?(Map_Battler) && !character.is_a?(Map_Battler)
  9203. # copy coordinates with correction
  9204. @x, @y = character.x * pix, character.y * pix
  9205. # if not battler and battler before
  9206. elsif !self.is_a?(Map_Battler) && character.is_a?(Map_Battler)
  9207. # copy coordinates with correction
  9208. @x, @y = character.x / pix, character.y / pix
  9209. else
  9210. # just copy coordinates
  9211. @x, @y = character.x, character.y
  9212. end
  9213. end
  9214. #----------------------------------------------------------------------------
  9215. # name
  9216. # Returns the event's name if the is one.
  9217. #----------------------------------------------------------------------------
  9218. def name
  9219. return (@event != nil ? @event.name : '')
  9220. end
  9221. #----------------------------------------------------------------------------
  9222. # move_toward_player
  9223. # Rerouting method.
  9224. #----------------------------------------------------------------------------
  9225. def move_toward_player
  9226. move_toward($game_player)
  9227. end
  9228. #----------------------------------------------------------------------------
  9229. # move_away_from_player
  9230. # Rerouting method.
  9231. #----------------------------------------------------------------------------
  9232. def move_away_from_player
  9233. move_away_from($game_player)
  9234. end
  9235. #----------------------------------------------------------------------------
  9236. # turn_toward_player
  9237. # Rerouting method.
  9238. #----------------------------------------------------------------------------
  9239. def turn_toward_player
  9240. turn_toward($game_player)
  9241. end
  9242. #----------------------------------------------------------------------------
  9243. # turn_away_from_player
  9244. # Rerouting method.
  9245. #----------------------------------------------------------------------------
  9246. def turn_away_from_player
  9247. turn_away_from($game_player)
  9248. end
  9249. #----------------------------------------------------------------------------
  9250. # move_toward
  9251. # character - the character
  9252. # Moves towards a character. (pixel movement)
  9253. #----------------------------------------------------------------------------
  9254. def move_toward(character)
  9255. # calculate differences in x and y
  9256. dx, dy = @real_x - character.real_x, @real_y - character.real_y
  9257. # determines where to move according to the x and y differences
  9258. if dx > 0 && dy > 0 # player is up left
  9259. move_upper_left
  9260. elsif dx > 0 && dy < 0 # player is down left
  9261. move_lower_left
  9262. elsif dx < 0 && dy > 0 # player is up right
  9263. move_upper_right
  9264. elsif dx < 0 && dy < 0 # player is down right
  9265. move_lower_right
  9266. elsif dx < 0 && dy == 0 # player is right
  9267. move_right
  9268. elsif dx > 0 && dy == 0 # player is left
  9269. move_left
  9270. elsif dx == 0 && dy < 0 # player is down
  9271. move_down
  9272. elsif dx == 0 && dy > 0 # player is up
  9273. move_up
  9274. end
  9275. end
  9276. #----------------------------------------------------------------------------
  9277. # move_away_from
  9278. # character - the character
  9279. # Moves away from a character. (pixel movement)
  9280. #----------------------------------------------------------------------------
  9281. def move_away_from(character)
  9282. # calculate differences in x and y
  9283. dx, dy = @real_x - character.real_x, @real_y - character.real_y
  9284. # determines where to move according to the x and y differences
  9285. if dx > 0 && dy > 0 # character is up left
  9286. move_lower_right
  9287. elsif dx > 0 && dy < 0 # character is down left
  9288. move_upper_right
  9289. elsif dx < 0 && dy > 0 # character is up right
  9290. move_lower_left
  9291. elsif dx < 0 && dy < 0 # character is down right
  9292. move_upper_left
  9293. elsif dx < 0 && dy == 0 # character is right
  9294. move_left
  9295. elsif dx > 0 && dy == 0 # character is left
  9296. move_right
  9297. elsif dx == 0 && dy < 0 # character is down
  9298. move_up
  9299. elsif dx == 0 && dy > 0 # character is up
  9300. move_down
  9301. end
  9302. end
  9303. #----------------------------------------------------------------------------
  9304. # move_away_random
  9305. # character - the character
  9306. # turn_enabled - determines whether the character should turn as well
  9307. # distance - distance
  9308. # Moves away from a character randomly. (pixel movement)
  9309. #----------------------------------------------------------------------------
  9310. def move_away_random(character, turn_enabled = true, distance = 1)
  9311. # calculate differences in x and y
  9312. dx, dy = @real_x - character.real_x, @real_y - character.real_y
  9313. # array of directions
  9314. dirs = ($game_system._8_way ? [1, 2, 3, 4, 6, 7, 8, 9] : [2, 4, 6, 8])
  9315. # determines where can't move according to the x and y differences
  9316. if dx > 0 && dy > 0 # character is up left
  9317. dirs -= [4, 7, 8]
  9318. elsif dx > 0 && dy < 0 # character is down left
  9319. dirs -= [1, 2, 4]
  9320. elsif dx < 0 && dy > 0 # character is up right
  9321. dirs -= [6, 8, 9]
  9322. elsif dx < 0 && dy < 0 # character is down right
  9323. dirs -= [2, 3, 6]
  9324. elsif dx < 0 && dy == 0 # character is right
  9325. dirs -= [3, 6, 9]
  9326. elsif dx > 0 && dy == 0 # character is left
  9327. dirs -= [1, 4, 7]
  9328. elsif dx == 0 && dy < 0 # character is down
  9329. dirs -= [1, 2, 3]
  9330. elsif dx == 0 && dy > 0 # character is up
  9331. dirs -= [7, 8, 9]
  9332. end
  9333. # choose a random direction from available directions
  9334. return case dirs[rand(dirs.size)]
  9335. when 1 then distance.to_i.times {move_lower_left}
  9336. when 2 then distance.to_i.times {move_down(turn_enabled)}
  9337. when 3 then distance.to_i.times {move_lower_right}
  9338. when 4 then distance.to_i.times {move_left(turn_enabled)}
  9339. when 6 then distance.to_i.times {move_right(turn_enabled)}
  9340. when 7 then distance.to_i.times {move_upper_left}
  9341. when 8 then distance.to_i.times {move_up(turn_enabled)}
  9342. when 9 then distance.to_i.times {move_upper_right}
  9343. end
  9344. end
  9345. #----------------------------------------------------------------------------
  9346. # turn_toward
  9347. # character - the character
  9348. # Turn towards a character. (pixel movement)
  9349. #----------------------------------------------------------------------------
  9350. def turn_toward(character)
  9351. # calculate differences in x and y
  9352. dx, dy = @real_x - character.real_x, @real_y - character.real_y
  9353. # determines where to turn according to the x and y differences
  9354. if dx < 0 && dx.abs >= dy.abs # character is right
  9355. turn_right
  9356. elsif dx > 0 && dx.abs >= dy.abs # character is left
  9357. turn_left
  9358. elsif dy < 0 # character is down
  9359. turn_down
  9360. elsif dy > 0 # character is up
  9361. turn_up
  9362. end
  9363. end
  9364. #----------------------------------------------------------------------------
  9365. # turn_away_from
  9366. # character - the character
  9367. # Turn away from a character. (pixel movement)
  9368. #----------------------------------------------------------------------------
  9369. def turn_away_from(character)
  9370. # calculate differences in x and y
  9371. dx, dy = @real_x - character.real_x, @real_y - character.real_y
  9372. # determines where to turn according to the x and y differences
  9373. if dx < 0 && dx.abs >= dy.abs # character is right
  9374. turn_left
  9375. elsif dx > 0 && dx.abs >= dy.abs # character is left
  9376. turn_right
  9377. elsif dy < 0 # character is down
  9378. turn_up
  9379. elsif dy > 0 # character is up
  9380. turn_down
  9381. end
  9382. end
  9383. #----------------------------------------------------------------------------
  9384. # dropped?
  9385. # Checks if the character is a dropped event.
  9386. #----------------------------------------------------------------------------
  9387. def dropped?
  9388. return (@terminate_count != nil)
  9389. end
  9390. #----------------------------------------------------------------------------
  9391. # hitbox
  9392. # returns a rectangle representing the hitbox in real coordinates.
  9393. #----------------------------------------------------------------------------
  9394. def hitbox
  9395. x = @real_x / 4 + 16 - @hitbox_width / 2
  9396. cy = (@center_sprite ? 16 - @hitbox_height / 2 : 32 - @hitbox_height)
  9397. y = @real_y / 4 + cy
  9398. return Rect.new(x, y, @hitbox_width, @hitbox_height)
  9399. end
  9400. #----------------------------------------------------------------------------
  9401. # phitbox
  9402. # returns a rectangle representing the hitbox in pixel coordinates.
  9403. #----------------------------------------------------------------------------
  9404. def phitbox
  9405. pscale = $BlizzABS.pixel / 32.0
  9406. sx = (self.is_a?(Map_Battler) ? self.x : self.x * $BlizzABS.pixel)
  9407. x = sx + (32 - @hitbox_width) * pscale / 2
  9408. cy = (@center_sprite ? 16 - @hitbox_height / 2 : 32 - @hitbox_height)
  9409. sy = (self.is_a?(Map_Battler) ? self.y : self.y * $BlizzABS.pixel)
  9410. y = sy + cy * pscale
  9411. return Rect.new(x, y, @hitbox_width * pscale, @hitbox_height * pscale)
  9412. end
  9413.  
  9414. end
  9415.  
  9416. #==============================================================================
  9417. # Game_Event
  9418. #------------------------------------------------------------------------------
  9419. # This class was redefined as non-pixel movement character to support pixel
  9420. # movement from other character types and ABSEAL update limitation in case
  9421. # Tons of Add-ons is not available.
  9422. #==============================================================================
  9423.  
  9424. class Game_Event
  9425.  
  9426. # setting all accessible variables
  9427. attr_accessor :respawn_ids
  9428. attr_accessor :respawn_time
  9429. attr_accessor :icon
  9430. attr_reader :event
  9431. attr_writer :lock_time
  9432. #----------------------------------------------------------------------------
  9433. # override update
  9434. #----------------------------------------------------------------------------
  9435. alias upd_player_blizzabs_later update
  9436. def update
  9437. # if event lock exists, not expired and no other event is running
  9438. if @event_lock != nil && @event_lock > 0 &&
  9439. !$game_system.map_interpreter.running?
  9440. # decrease event lock timer
  9441. @event_lock -= 1
  9442. end
  9443. # if termination counter exists
  9444. if @terminate_count != nil
  9445. # decrease stay time if stay time is greater than 0
  9446. @terminate_count -= 1 if @terminate_count > 0
  9447. # set deletion flag if item taken or stay time expired
  9448. erase if @terminate_count <= 0
  9449. end
  9450. # call original method if within ABSEAL range
  9451. upd_player_blizzabs_later if update?
  9452. end
  9453. #----------------------------------------------------------------------------
  9454. # override refresh
  9455. # A flag addition was added to this method.
  9456. #----------------------------------------------------------------------------
  9457. alias refresh_blizzabs_later refresh
  9458. def refresh
  9459. # call original method
  9460. refresh_blizzabs_later
  9461. # test command list on teleport command if command list exists
  9462. @teleport = (@list != nil && @list.any? {|i| i.code == 201})
  9463. # activate drop mode if dropped
  9464. activate_drop_mode if dropped?
  9465. end
  9466. #----------------------------------------------------------------------------
  9467. # override start
  9468. # Has been enhanced to support the event lock feature.
  9469. #----------------------------------------------------------------------------
  9470. alias start_blizzabs_later start
  9471. def start
  9472. # stop if event lock not expired yet
  9473. return if @event_lock != nil && @event_lock > 0
  9474. # call original method
  9475. start_blizzabs_later
  9476. # set event lock if activated by touch
  9477. @event_lock = @lock_time if @trigger == 1 || @trigger == 2
  9478. end
  9479. #----------------------------------------------------------------------------
  9480. # override erase
  9481. #----------------------------------------------------------------------------
  9482. alias erase_blizzabs_later erase
  9483. def erase
  9484. @terminate = true
  9485. erase_blizzabs_later
  9486. end
  9487. #----------------------------------------------------------------------------
  9488. # passable?
  9489. # x - x-coordinate
  9490. # y - y-coordinate
  9491. # d - facing direction
  9492. # Checks if the tile is passable.
  9493. #----------------------------------------------------------------------------
  9494. def passable?(x, y, d)
  9495. # get new coordinates
  9496. nx, ny = x+(d == 6 ? 1 : d == 4 ? -1 : 0), y+(d == 2 ? 1 : d == 8 ? -1 : 0)
  9497. # not passable if coordinates are outside of map
  9498. return false unless $game_map.valid?(nx, ny)
  9499. # passable if through is ON
  9500. return true if @through
  9501. # not passable if unable to leave current tile in designated direction
  9502. return false unless $game_map.passable?(x, y, d, self)
  9503. # not passable if unable to enter move tile in designated direction
  9504. return false unless $game_map.passable?(nx, ny, 10 - d)
  9505. # if any event on new position and not through
  9506. if $game_map.events_only.any? {|event|
  9507. !event.through && event.x == nx && event.y == ny}
  9508. # impassable
  9509. return false
  9510. end
  9511. # passable if no spriteset
  9512. return true if @character_name == ''
  9513. # get pixel movement rate
  9514. pix = $BlizzABS.pixel
  9515. # rectangle
  9516. rect = Rect.new(nx * pix, ny * pix, pix, pix)
  9517. # if any battler in the way
  9518. if ($BlizzABS.battlers + $game_map.battlers).any? {|battler|
  9519. !battler.through && battler.character_name != '' &&
  9520. $BlizzABS.util.rect_intersection(rect, battler.phitbox)}
  9521. #Rect.new(battler.x, battler.y, pix, pix))}
  9522. # impassable
  9523. return false
  9524. end
  9525. # passable
  9526. return true
  9527. end
  9528. #----------------------------------------------------------------------------
  9529. # check_event_trigger_touch
  9530. # x - x-coordinate
  9531. # y - y-coordinate
  9532. # Check event if was triggered by touch. (pixel movement)
  9533. #----------------------------------------------------------------------------
  9534. def check_event_trigger_touch(x, y)
  9535. # stop check if map interpreter is already running
  9536. return false if $game_system.map_interpreter.running? || @trigger != 2
  9537. # get pixel movement rate
  9538. pix = $BlizzABS.pixel
  9539. # if player touched this event and not jumping and not over_trigger
  9540. if !jumping? && !over_trigger? &&
  9541. $BlizzABS.util.rect_intersection(Rect.new(x * pix, y * pix, pix, pix),
  9542. Rect.new($game_player.x, $game_player.y, pix, pix))
  9543. # start
  9544. raise @trigger.to_s
  9545. start
  9546. # started
  9547. return true
  9548. end
  9549. # not started
  9550. return false
  9551. end
  9552. #----------------------------------------------------------------------------
  9553. # check_event_trigger_auto
  9554. # Check event if was triggered automatically. (pixel movement)
  9555. #----------------------------------------------------------------------------
  9556. def check_event_trigger_auto
  9557. # if triggered by event touch
  9558. if @trigger == 2
  9559. # check player touch
  9560. return check_event_trigger_at($game_player.x, $game_player.y)
  9561. # if autorun
  9562. elsif @trigger == 3
  9563. # start
  9564. start
  9565. # started
  9566. return true
  9567. end
  9568. # not started
  9569. return false
  9570. end
  9571. #----------------------------------------------------------------------------
  9572. # check_event_trigger_at
  9573. # x - x-coordinate
  9574. # y - y-coordinate
  9575. # Check event if it was triggered at a specific position. (pixel movement)
  9576. #----------------------------------------------------------------------------
  9577. def check_event_trigger_at(x, y)
  9578. # get pixel movement rate
  9579. pix = $BlizzABS.pixel
  9580. # if player touched this event and not jumping and not over_trigger
  9581. if !jumping? && !over_trigger? && $BlizzABS.util.rect_intersection(
  9582. self.phitbox, Rect.new(x, y, pix, pix))
  9583. # start
  9584. start
  9585. # started
  9586. return true
  9587. end
  9588. # not started
  9589. return false
  9590. end
  9591. #----------------------------------------------------------------------------
  9592. # set_real_position
  9593. # real_x - new real x-coordinate
  9594. # real_y - new real y-coordinate
  9595. # Sets the real positions of the event.
  9596. #----------------------------------------------------------------------------
  9597. def set_real_position(real_x, real_y)
  9598. @real_x, @real_y = real_x, real_y
  9599. end
  9600. #----------------------------------------------------------------------------
  9601. # activate_drop_mode
  9602. # time - countdown timer
  9603. # Sets up everything for an event to act like a dropped event.
  9604. #----------------------------------------------------------------------------
  9605. def activate_drop_mode(time = @terminate_count)
  9606. # set disappearance counter
  9607. @terminate_count = time
  9608. # set moving speed
  9609. @move_speed = 6
  9610. # set moving frequency
  9611. @move_frequency = 6
  9612. # set step anime
  9613. @step_anime = true
  9614. # set direction fix
  9615. @direction_fix = true
  9616. end
  9617.  
  9618. end
Add Comment
Please, Sign In to add comment