Advertisement
Guest User

Untitled

a guest
Jul 26th, 2015
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 45.55 KB | None | 0 0
  1. class PBTargets
  2. SingleNonUser = 0x00
  3. NoTarget = 0x01
  4. RandomOpposing = 0x02
  5. AllOpposing = 0x04
  6. AllNonUsers = 0x08
  7. User = 0x10
  8. UserSide = 0x20
  9. BothSides = 0x40
  10. OpposingSide = 0x80
  11. Partner = 0x100
  12. UserOrPartner = 0x200
  13. SingleOpposing = 0x400
  14. OppositeOpposing = 0x800
  15. end
  16.  
  17.  
  18.  
  19. class PokeBattle_Move
  20. attr_accessor(:id)
  21. attr_reader(:battle)
  22. attr_reader(:name)
  23. attr_reader(:function)
  24. attr_reader(:basedamage)
  25. attr_reader(:type)
  26. attr_reader(:accuracy)
  27. attr_reader(:addlEffect)
  28. attr_reader(:target)
  29. attr_reader(:priority)
  30. attr_reader(:flags)
  31. attr_reader(:thismove)
  32. attr_accessor(:pp)
  33. attr_accessor(:totalpp)
  34.  
  35. NOTYPE = 0x01
  36. IGNOREPKMNTYPES = 0x02
  37. NOWEIGHTING = 0x04
  38. NOCRITICAL = 0x08
  39. NOREFLECT = 0x10
  40. SELFCONFUSE = 0x20
  41.  
  42. ################################################################################
  43. # Creating a move
  44. ################################################################################
  45. def initialize(battle,move)
  46. @id = move.id
  47. @battle = battle
  48. @name = PBMoves.getName(id) # Get the move's name
  49. # Get data on the move
  50. movedata = PBMoveData.new(id)
  51. @function = movedata.function
  52. @basedamage = movedata.basedamage
  53. @type = movedata.type
  54. @accuracy = movedata.accuracy
  55. @addlEffect = movedata.addlEffect
  56. @target = movedata.target
  57. @priority = movedata.priority
  58. @flags = movedata.flags
  59. @category = movedata.category
  60. @thismove = move
  61. @pp = move.pp # Can be changed with Mimic/Transform
  62. end
  63.  
  64. # This is the code actually used to generate a PokeBattle_Move object. The
  65. # object generated is a subclass of this one which depends on the move's
  66. # function code (found in the script section PokeBattle_MoveEffect).
  67. def PokeBattle_Move.pbFromPBMove(battle,move)
  68. move=PBMove.new(0) if !move
  69. movedata=PBMoveData.new(move.id)
  70. className=sprintf("PokeBattle_Move_%03X",movedata.function)
  71. if Object.const_defined?(className)
  72. return Kernel.const_get(className).new(battle,move)
  73. else
  74. return PokeBattle_UnimplementedMove.new(battle,move)
  75. end
  76. end
  77.  
  78. ################################################################################
  79. # About the move
  80. ################################################################################
  81. def totalpp
  82. return @totalpp if @totalpp && @totalpp>0
  83. return @thismove.totalpp if @thismove
  84. end
  85.  
  86. def to_int
  87. return @id
  88. end
  89.  
  90. def pbType(type,attacker,opponent)
  91. if type>=0 && isConst?(attacker.ability,PBAbilities,:NORMALIZE)
  92. type=getConst(PBTypes,:NORMAL) || 0
  93. end
  94. return type
  95. end
  96.  
  97. def pbIsPhysical?(type,attacker=nil)
  98. if USEMOVECATEGORY
  99. return @category==0
  100. else
  101. return !PBTypes.isSpecialType?(type)
  102. end
  103. end
  104.  
  105. def pbIsSpecial?(type,attacker=nil)
  106. if USEMOVECATEGORY
  107. return @category==1
  108. else
  109. return PBTypes.isSpecialType?(type)
  110. end
  111. end
  112.  
  113. def pbTargetsAll?(attacker)
  114. if @target==PBTargets::AllOpposing # All opposing Pokémon
  115. # TODO: should apply even if partner faints during an attack
  116. return attacker.pbOpposing1.hp>0 && attacker.pbOpposing2.hp>0
  117. end
  118. return false
  119. end
  120.  
  121. def pbNumHits
  122. return 1
  123. end
  124.  
  125. def pbIsMultiHit # not the same as pbNumHits>1
  126. return false
  127. end
  128.  
  129. def pbTwoTurnAttack(attacker)
  130. return false
  131. end
  132.  
  133. def pbAdditionalEffect(attacker,opponent)
  134. end
  135.  
  136. ################################################################################
  137. # This move's type effectiveness
  138. ################################################################################
  139. def pbTypeModifier(type,attacker,opponent)
  140. return 4 if type<0
  141. return 4 if isConst?(type,PBTypes,:GROUND) && opponent.pbHasType?(:FLYING) &&
  142. isConst?(opponent.item,PBItems,:IRONBALL)
  143. atype=type # attack type
  144. otype1=opponent.type1
  145. otype2=opponent.type2
  146. if isConst?(otype1,PBTypes,:FLYING) && opponent.effects[PBEffects::Roost]
  147. if isConst?(otype2,PBTypes,:FLYING)
  148. otype1=getConst(PBTypes,:NORMAL) || 0
  149. else
  150. otype1=otype2
  151. end
  152. end
  153. if isConst?(otype2,PBTypes,:FLYING) && opponent.effects[PBEffects::Roost]
  154. otype2=otype1
  155. end
  156. mod1=PBTypes.getEffectiveness(atype,otype1)
  157. mod2=(otype1==otype2) ? 2 : PBTypes.getEffectiveness(atype,otype2)
  158. if isConst?(opponent.item,PBItems,:RINGTARGET)
  159. mod1=2 if mod1==0
  160. mod2=2 if mod2==0
  161. end
  162. if isConst?(attacker.ability,PBAbilities,:SCRAPPY) ||
  163. opponent.effects[PBEffects::Foresight]
  164. mod1=2 if isConst?(otype1,PBTypes,:GHOST) &&
  165. (isConst?(atype,PBTypes,:NORMAL) || isConst?(atype,PBTypes,:FIGHTING))
  166. mod2=2 if isConst?(otype2,PBTypes,:GHOST) &&
  167. (isConst?(atype,PBTypes,:NORMAL) || isConst?(atype,PBTypes,:FIGHTING))
  168. end
  169. if opponent.effects[PBEffects::Ingrain] ||
  170. opponent.effects[PBEffects::SmackDown] ||
  171. attacker.pbOwnSide.effects[PBEffects::Gravity]>0 ||
  172. attacker.pbOpposingSide.effects[PBEffects::Gravity]>0
  173. mod1=2 if isConst?(otype1,PBTypes,:FLYING) && isConst?(atype,PBTypes,:GROUND)
  174. mod2=2 if isConst?(otype2,PBTypes,:FLYING) && isConst?(atype,PBTypes,:GROUND)
  175. end
  176. if opponent.effects[PBEffects::MiracleEye]
  177. mod1=2 if isConst?(otype1,PBTypes,:DARK) && isConst?(atype,PBTypes,:PSYCHIC)
  178. mod2=2 if isConst?(otype2,PBTypes,:DARK) && isConst?(atype,PBTypes,:PSYCHIC)
  179. end
  180. return mod1*mod2
  181. end
  182.  
  183. def pbTypeModMessages(type,attacker,opponent)
  184. return 4 if type<0
  185. if opponent.hp>0
  186. if isConst?(opponent.ability,PBAbilities,:FLASHFIRE) &&
  187. isConst?(type,PBTypes,:FIRE)
  188. if !opponent.effects[PBEffects::FlashFire]
  189. opponent.effects[PBEffects::FlashFire]=true
  190. @battle.pbDisplay(_INTL("{1}'s {2} raised its FIRE power!",
  191. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  192. else
  193. @battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",
  194. opponent.pbThis,PBAbilities.getName(opponent.ability),self.name))
  195. end
  196. return 0
  197. end
  198. if (isConst?(opponent.ability,PBAbilities,:STORMDRAIN) && isConst?(type,PBTypes,:WATER)) ||
  199. (isConst?(opponent.ability,PBAbilities,:LIGHTNINGROD) && isConst?(type,PBTypes,:ELECTRIC))
  200. if opponent.pbCanIncreaseStatStage?(PBStats::SPATK)
  201. opponent.pbIncreaseStatBasic(PBStats::SPATK,1)
  202. @battle.pbCommonAnimation("StatUp",opponent,nil)
  203. @battle.pbDisplay(_INTL("{1}'s {2} raised its SP. ATTACK!",
  204. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  205. else
  206. @battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",
  207. opponent.pbThis,PBAbilities.getName(opponent.ability),self.name))
  208. end
  209. return 0
  210. end
  211. if isConst?(opponent.ability,PBAbilities,:MOTORDRIVE) &&
  212. isConst?(type,PBTypes,:ELECTRIC)
  213. if opponent.pbCanIncreaseStatStage?(PBStats::SPEED)
  214. opponent.pbIncreaseStatBasic(PBStats::SPEED,1)
  215. @battle.pbCommonAnimation("StatUp",opponent,nil)
  216. @battle.pbDisplay(_INTL("{1}'s {2} raised its SPEED!",
  217. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  218. else
  219. @battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",
  220. opponent.pbThis,PBAbilities.getName(opponent.ability),self.name))
  221. end
  222. return 0
  223. end
  224. if isConst?(opponent.ability,PBAbilities,:SAPSIPPER) &&
  225. isConst?(type,PBTypes,:GRASS)
  226. if opponent.pbCanIncreaseStatStage?(PBStats::ATTACK)
  227. opponent.pbIncreaseStatBasic(PBStats::ATTACK,1)
  228. @battle.pbCommonAnimation("StatUp",opponent,nil)
  229. @battle.pbDisplay(_INTL("{1}'s {2} raised its ATTACK!",
  230. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  231. else
  232. @battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",
  233. opponent.pbThis,PBAbilities.getName(opponent.ability),self.name))
  234. end
  235. return 0
  236. end
  237. if (isConst?(opponent.ability,PBAbilities,:DRYSKIN) && isConst?(type,PBTypes,:WATER)) ||
  238. (isConst?(opponent.ability,PBAbilities,:VOLTABSORB) && isConst?(type,PBTypes,:ELECTRIC)) ||
  239. (isConst?(opponent.ability,PBAbilities,:WATERABSORB) && isConst?(type,PBTypes,:WATER))
  240. if opponent.effects[PBEffects::HealBlock]==0
  241. if opponent.pbRecoverHP((opponent.totalhp/4).floor,true)==0
  242. @battle.pbDisplay(_INTL("{1}'s {2} made {3} useless!",
  243. opponent.pbThis,PBAbilities.getName(opponent.ability),@name))
  244. else
  245. @battle.pbDisplay(_INTL("{1}'s {2} restored its HP!",
  246. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  247. end
  248. return 0
  249. end
  250. end
  251. end
  252. typemod=pbTypeModifier(type,attacker,opponent)
  253. if typemod==0
  254. @battle.pbDisplay(_INTL("It doesn't affect {1}...",opponent.pbThis(true)))
  255. end
  256. return typemod
  257. end
  258.  
  259. ################################################################################
  260. # This move's accuracy check
  261. ################################################################################
  262. def pbAccuracyCheck(attacker,opponent)
  263. baseaccuracy=@accuracy
  264. return true if baseaccuracy==0
  265. return true if isConst?(attacker.ability,PBAbilities,:NOGUARD) ||
  266. isConst?(opponent.ability,PBAbilities,:NOGUARD)
  267. return true if opponent.effects[PBEffects::Telekinesis]>0
  268. # One-hit KO accuracy handled elsewhere
  269. if @function==0x08 || @function==0x15 # Thunder or Hurricane
  270. baseaccuracy=50 if @battle.pbWeather==PBWeather::SUNNYDAY
  271. baseaccuracy=100 if @battle.pbWeather==PBWeather::RAINDANCE
  272. end
  273. if @function==0x0D # Blizzard
  274. baseaccuracy=100 if @battle.pbWeather==PBWeather::HAIL
  275. end
  276. accstage=attacker.stages[PBStats::ACCURACY]
  277. accstage=0 if isConst?(opponent.ability,PBAbilities,:UNAWARE)
  278. accuracy=(accstage>=0) ? (accstage+3)*100.0/3 : 300.0/(3-accstage)
  279. evastage=opponent.stages[PBStats::EVASION]
  280. evastage-=2 if attacker.pbOwnSide.effects[PBEffects::Gravity]>0 ||
  281. attacker.pbOpposingSide.effects[PBEffects::Gravity]>0
  282. evastage=-6 if evastage<-6
  283. evastage=0 if opponent.effects[PBEffects::Foresight] ||
  284. opponent.effects[PBEffects::MiracleEye] ||
  285. @function==0xA9 || # Chip Away
  286. isConst?(attacker.ability,PBAbilities,:UNAWARE)
  287. evasion=(evastage>=0) ? (evastage+3)*100.0/3 : 300.0/(3-evastage)
  288. if isConst?(attacker.ability,PBAbilities,:COMPOUNDEYES)
  289. accuracy*=1.3
  290. end
  291. if isConst?(attacker.item,PBItems,:MICLEBERRY)
  292. if (isConst?(attacker.ability,PBAbilities,:GLUTTONY) && attacker.hp<=(attacker.totalhp/2).floor) ||
  293. attacker.hp<=(attacker.totalhp/4).floor
  294. accuracy*=1.2
  295. attacker.pokemon.itemRecycle=attacker.item
  296. attacker.pokemon.itemInitial=0 if attacker.pokemon.itemInitial==attacker.item
  297. attacker.item=0
  298. end
  299. end
  300. if isConst?(attacker.ability,PBAbilities,:VICTORYSTAR)
  301. accuracy*=1.1
  302. end
  303. partner=attacker.pbPartner
  304. if partner && isConst?(partner.ability,PBAbilities,:VICTORYSTAR)
  305. accuracy*=1.1
  306. end
  307. if isConst?(attacker.item,PBItems,:WIDELENS)
  308. accuracy*=1.1
  309. end
  310. if isConst?(attacker.ability,PBAbilities,:HUSTLE) && @basedamage>0 &&
  311. pbIsPhysical?(pbType(@type,attacker=nil,opponent))
  312. accuracy*=0.8
  313. end
  314. if isConst?(opponent.ability,PBAbilities,:WONDERSKIN) && @basedamage==0 &&
  315. attacker.pbIsOpposing?(opponent.index)
  316. accuracy/=2
  317. end
  318. if isConst?(opponent.ability,PBAbilities,:TANGLEDFEET) &&
  319. opponent.effects[PBEffects::Confusion]>0
  320. evasion*=1.2
  321. end
  322. if @battle.pbWeather==PBWeather::SANDSTORM && isConst?(opponent.ability,PBAbilities,:SANDVEIL)
  323. evasion*=1.2
  324. end
  325. if @battle.pbWeather==PBWeather::HAIL && isConst?(opponent.ability,PBAbilities,:SNOWCLOAK)
  326. evasion*=1.2
  327. end
  328. if isConst?(opponent.item,PBItems,:BRIGHTPOWDER)
  329. evasion*=1.1
  330. end
  331. if isConst?(opponent.item,PBItems,:LAXINCENSE)
  332. evasion*=1.1
  333. end
  334. return @battle.pbRandom(100)<(baseaccuracy*accuracy/evasion)
  335. end
  336.  
  337. ################################################################################
  338. # Damage calculation and modifiers
  339. ################################################################################
  340. def pbIsCritical?(attacker,opponent)
  341. if isConst?(opponent.ability,PBAbilities,:BATTLEARMOR) ||
  342. isConst?(opponent.ability,PBAbilities,:SHELLARMOR)
  343. return false
  344. end
  345. return false if opponent.pbOwnSide.effects[PBEffects::LuckyChant]>0
  346. return true if @function==0xA0 # Frost Breath
  347. c=0
  348. ratios=[16,8,4,3,2]
  349. c+=attacker.effects[PBEffects::FocusEnergy]
  350. c+=1 if (@flags&0x80)!=0 # flag h: Has high critical hit rate
  351. if (attacker.inHyperMode? rescue false) && isConst?(self.type,PBTypes,:SHADOW)
  352. c+=1
  353. end
  354. if isConst?(attacker.species,PBSpecies,:CHANSEY) &&
  355. isConst?(attacker.item,PBItems,:LUCKYPUNCH)
  356. c+=2
  357. end
  358. if isConst?(attacker.species,PBSpecies,:FARFETCHD) &&
  359. isConst?(attacker.item,PBItems,:STICK)
  360. c+=2
  361. end
  362. c+=1 if isConst?(attacker.ability,PBAbilities,:SUPERLUCK)
  363. c+=1 if isConst?(attacker.item,PBItems,:SCOPELENS)
  364. c+=1 if isConst?(attacker.item,PBItems,:RAZORCLAW)
  365. c=4 if c>4
  366. return @battle.pbRandom(ratios[c])==0
  367. end
  368.  
  369. def pbBaseDamage(basedmg,attacker,opponent)
  370. return basedmg
  371. end
  372.  
  373. def pbCalcDamage(attacker,opponent,options=0)
  374. opponent.damagestate.critical=false
  375. opponent.damagestate.typemod=0
  376. opponent.damagestate.calcdamage=0
  377. opponent.damagestate.hplost=0
  378. return 0 if @basedamage==0
  379. if (options&NOCRITICAL)==0
  380. opponent.damagestate.critical=pbIsCritical?(attacker,opponent)
  381. end
  382. stagemul=[10,10,10,10,10,10,10,15,20,25,30,35,40]
  383. stagediv=[40,35,30,25,20,15,10,10,10,10,10,10,10]
  384. basedmg=@basedamage
  385. basedmg=pbBaseDamage(basedmg,attacker,opponent)
  386. if (options&NOTYPE)==0
  387. type=pbType(@type,attacker,opponent)
  388. else
  389. type=-1 # Will be treated as physical
  390. end
  391. atk=attacker.attack
  392. defense=opponent.defense
  393. spatk=attacker.spatk
  394. spdef=opponent.spdef
  395. # Gym Badges (internal battles only)
  396. if @battle.internalbattle
  397. if @battle.pbOwnedByPlayer?(attacker.index)
  398. atk=(atk*1.1).floor if @battle.pbPlayer.numbadges>=BADGESBOOSTATTACK
  399. end
  400. if @battle.pbOwnedByPlayer?(opponent.index)
  401. defense=(defense*1.1).floor if @battle.pbPlayer.numbadges>=BADGESBOOSTDEFENSE
  402. end
  403. if @battle.pbOwnedByPlayer?(attacker.index)
  404. spatk=(spatk*1.1).floor if @battle.pbPlayer.numbadges>=BADGESBOOSTSPATK
  405. end
  406. if @battle.pbOwnedByPlayer?(opponent.index)
  407. spdef=(spdef*1.1).floor if @battle.pbPlayer.numbadges>=BADGESBOOSTSPDEF
  408. end
  409. end
  410. #Stat Stages
  411. atkstage=attacker.stages[PBStats::ATTACK]+6
  412. spatkstage=attacker.stages[PBStats::SPATK]+6
  413. defstage=opponent.stages[PBStats::DEFENSE]+6
  414. spdefstage=opponent.stages[PBStats::SPDEF]+6
  415. defstage=spdefstage=6 if @function==0xA9 # Chip Away
  416. if isConst?(attacker.ability,PBAbilities,:UNAWARE)
  417. defstage=spdefstage=6
  418. end
  419. if isConst?(opponent.ability,PBAbilities,:UNAWARE)
  420. atkstage=spatkstage=6
  421. end
  422. if opponent.damagestate.critical
  423. atkstage=6 if atkstage<6
  424. spatkstage=6 if spatkstage<6
  425. defstage=6 if defstage>6
  426. spdefstage=6 if spdefstage>6
  427. end
  428. atk=(atk*stagemul[atkstage]/stagediv[atkstage]).floor
  429. spatk=(spatk*stagemul[spatkstage]/stagediv[spatkstage]).floor
  430. defense=(defense*stagemul[defstage]/stagediv[defstage]).floor
  431. spdef=(spdef*stagemul[spdefstage]/stagediv[spdefstage]).floor
  432. # Helping Hand
  433. if attacker.effects[PBEffects::HelpingHand] && (options&SELFCONFUSE)==0
  434. basedmg=(basedmg*1.5).floor
  435. end
  436. if isConst?(attacker.ability,PBAbilities,:TECHNICIAN) && basedmg<=60
  437. basedmg=(basedmg*1.5).floor
  438. end
  439. if isConst?(opponent.ability,PBAbilities,:MARVELSCALE) && opponent.status>0
  440. defense=(defense*1.5).floor
  441. end
  442. if opponent.pbHasType?(:ROCK) && @battle.pbWeather==PBWeather::SANDSTORM
  443. spdef=(spdef*1.5).floor
  444. end
  445. if isConst?(opponent.item,PBItems,:EVIOLITE)
  446. evos=pbGetEvolvedFormData(opponent.species)
  447. if evos && evos.length>0
  448. defense=(defense*1.5).floor
  449. spdef=(spdef*1.5).floor
  450. end
  451. end
  452. # Type boosting items
  453. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:SILKSCARF) && isConst?(type,PBTypes,:NORMAL)
  454. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:BLACKBELT) && isConst?(type,PBTypes,:FIGHTING)
  455. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:SHARPBEAK) && isConst?(type,PBTypes,:FLYING)
  456. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:POISONBARB) && isConst?(type,PBTypes,:POISON)
  457. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:SOFTSAND) && isConst?(type,PBTypes,:GROUND)
  458. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:HARDSTONE) && isConst?(type,PBTypes,:ROCK)
  459. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:SILVERPOWDER) && isConst?(type,PBTypes,:BUG)
  460. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:SPELLTAG) && isConst?(type,PBTypes,:GHOST)
  461. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:METALCOAT) && isConst?(type,PBTypes,:STEEL)
  462. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:CHARCOAL) && isConst?(type,PBTypes,:FIRE)
  463. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:MYSTICWATER) && isConst?(type,PBTypes,:WATER)
  464. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:MIRACLESEED) && isConst?(type,PBTypes,:GRASS)
  465. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:MAGNET) && isConst?(type,PBTypes,:ELECTRIC)
  466. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:TWISTEDSPOON) && isConst?(type,PBTypes,:PSYCHIC)
  467. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:NEVERMELTICE) && isConst?(type,PBTypes,:ICE)
  468. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:DRAGONFANG) && isConst?(type,PBTypes,:DRAGON)
  469. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:BLACKGLASSES) && isConst?(type,PBTypes,:DARK)
  470. # Plates
  471. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:FISTPLATE) && isConst?(type,PBTypes,:FIGHTING)
  472. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:SKYPLATE) && isConst?(type,PBTypes,:FLYING)
  473. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:TOXICPLATE) && isConst?(type,PBTypes,:POISON)
  474. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:EARTHPLATE) && isConst?(type,PBTypes,:GROUND)
  475. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:STONEPLATE) && isConst?(type,PBTypes,:ROCK)
  476. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:INSECTPLATE) && isConst?(type,PBTypes,:BUG)
  477. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:SPOOKYPLATE) && isConst?(type,PBTypes,:GHOST)
  478. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:IRONPLATE) && isConst?(type,PBTypes,:STEEL)
  479. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:FLAMEPLATE) && isConst?(type,PBTypes,:FIRE)
  480. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:SPLASHPLATE) && isConst?(type,PBTypes,:WATER)
  481. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:MEADOWPLATE) && isConst?(type,PBTypes,:GRASS)
  482. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:ZAPPLATE) && isConst?(type,PBTypes,:ELECTRIC)
  483. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:MINDPLATE) && isConst?(type,PBTypes,:PSYCHIC)
  484. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:ICICLEPLATE) && isConst?(type,PBTypes,:ICE)
  485. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:DRACOPLATE) && isConst?(type,PBTypes,:DRAGON)
  486. basedmg=(basedmg*1.2).floor if isConst?(attacker.item,PBItems,:DREADPLATE) && isConst?(type,PBTypes,:DARK)
  487. # Gems
  488. if (isConst?(attacker.item,PBItems,:NORMALGEM) && isConst?(type,PBTypes,:NORMAL)) ||
  489. (isConst?(attacker.item,PBItems,:FIGHTINGGEM) && isConst?(type,PBTypes,:FIGHTING)) ||
  490. (isConst?(attacker.item,PBItems,:FLYINGGEM) && isConst?(type,PBTypes,:FLYING)) ||
  491. (isConst?(attacker.item,PBItems,:POISONGEM) && isConst?(type,PBTypes,:POISON)) ||
  492. (isConst?(attacker.item,PBItems,:GROUNDGEM) && isConst?(type,PBTypes,:GROUND)) ||
  493. (isConst?(attacker.item,PBItems,:ROCKGEM) && isConst?(type,PBTypes,:ROCK)) ||
  494. (isConst?(attacker.item,PBItems,:BUGGEM) && isConst?(type,PBTypes,:BUG)) ||
  495. (isConst?(attacker.item,PBItems,:GHOSTGEM) && isConst?(type,PBTypes,:GHOST)) ||
  496. (isConst?(attacker.item,PBItems,:STEELGEM) && isConst?(type,PBTypes,:STEEL)) ||
  497. (isConst?(attacker.item,PBItems,:FIREGEM) && isConst?(type,PBTypes,:FIRE)) ||
  498. (isConst?(attacker.item,PBItems,:WATERGEM) && isConst?(type,PBTypes,:WATER)) ||
  499. (isConst?(attacker.item,PBItems,:GRASSGEM) && isConst?(type,PBTypes,:GRASS)) ||
  500. (isConst?(attacker.item,PBItems,:ELECTRICGEM) && isConst?(type,PBTypes,:ELECTRIC)) ||
  501. (isConst?(attacker.item,PBItems,:PSYCHICGEM) && isConst?(type,PBTypes,:PSYCHIC)) ||
  502. (isConst?(attacker.item,PBItems,:ICEGEM) && isConst?(type,PBTypes,:ICE)) ||
  503. (isConst?(attacker.item,PBItems,:DRAGONGEM) && isConst?(type,PBTypes,:DRAGON)) ||
  504. (isConst?(attacker.item,PBItems,:DARKGEM) && isConst?(type,PBTypes,:DARK))
  505. basedmg=(basedmg*1.5).floor
  506. attacker.pokemon.itemRecycle=attacker.item
  507. attacker.pokemon.itemInitial=0 if attacker.pokemon.itemInitial==attacker.item
  508. attacker.item=0
  509. end
  510. if isConst?(attacker.item,PBItems,:ROCKINCENSE) && isConst?(type,PBTypes,:ROCK)
  511. basedmg=(basedmg*1.2).floor
  512. end
  513. if isConst?(attacker.item,PBItems,:ROSEINCENSE) && isConst?(type,PBTypes,:GRASS)
  514. basedmg=(basedmg*1.2).floor
  515. end
  516. if isConst?(attacker.item,PBItems,:SEAINCENSE) && isConst?(type,PBTypes,:WATER)
  517. basedmg=(basedmg*1.2).floor
  518. end
  519. if isConst?(attacker.item,PBItems,:WAVEINCENSE) && isConst?(type,PBTypes,:WATER)
  520. basedmg=(basedmg*1.2).floor
  521. end
  522. if isConst?(attacker.item,PBItems,:ODDINCENSE) && isConst?(type,PBTypes,:PSYCHIC)
  523. basedmg=(basedmg*1.2).floor
  524. end
  525. atk=(atk*1.5).floor if isConst?(attacker.item,PBItems,:CHOICEBAND)
  526. spatk=(spatk*1.5).floor if isConst?(attacker.item,PBItems,:CHOICESPECS)
  527. if isConst?(attacker.species,PBSpecies,:PIKACHU) && isConst?(attacker.item,PBItems,:LIGHTBALL)
  528. basedmg*=2
  529. end
  530. if (isConst?(attacker.species,PBSpecies,:CUBONE) ||
  531. isConst?(attacker.species,PBSpecies,:MAROWAK)) &&
  532. isConst?(attacker.item,PBItems,:THICKCLUB)
  533. atk*=2
  534. end
  535. if isConst?(opponent.species,PBSpecies,:DITTO) && !opponent.effects[PBEffects::Transform] &&
  536. isConst?(opponent.item,PBItems,:METALPOWDER)
  537. basedmg/=2
  538. end
  539. if isConst?(attacker.species,PBSpecies,:CLAMPERL) &&
  540. isConst?(attacker.item,PBItems,:DEEPSEATOOTH)
  541. spatk*=2
  542. end
  543. if isConst?(opponent.species,PBSpecies,:CLAMPERL) &&
  544. isConst?(opponent.item,PBItems,:DEEPSEASCALE)
  545. spdef*=2
  546. end
  547. if (isConst?(attacker.species,PBSpecies,:LATIAS) ||
  548. isConst?(attacker.species,PBSpecies,:LATIOS)) &&
  549. isConst?(attacker.item,PBItems,:SOULDEW) && !@battle.rules["souldewclause"]
  550. spatk*=1.5
  551. end
  552. if (isConst?(opponent.species,PBSpecies,:LATIAS) ||
  553. isConst?(opponent.species,PBSpecies,:LATIOS)) &&
  554. isConst?(opponent.item,PBItems,:SOULDEW) && !@battle.rules["souldewclause"]
  555. spdef*=1.5
  556. end
  557. if isConst?(attacker.species,PBSpecies,:DIALGA) &&
  558. isConst?(attacker.item,PBItems,:ADAMANTORB) &&
  559. (isConst?(type,PBTypes,:DRAGON) || isConst?(type,PBTypes,:STEEL))
  560. basedmg=(basedmg*1.2).floor
  561. end
  562. if isConst?(attacker.species,PBSpecies,:PALKIA) &&
  563. isConst?(attacker.item,PBItems,:LUSTROUSORB) &&
  564. (isConst?(type,PBTypes,:DRAGON) || isConst?(type,PBTypes,:WATER))
  565. basedmg=(basedmg*1.2).floor
  566. end
  567. if isConst?(attacker.species,PBSpecies,:GIRATINA) &&
  568. isConst?(attacker.item,PBItems,:GRISEOUSORB) &&
  569. (isConst?(type,PBTypes,:DRAGON) || isConst?(type,PBTypes,:GHOST))
  570. basedmg=(basedmg*1.2).floor
  571. end
  572. if isConst?(opponent.ability,PBAbilities,:MULTISCALE) && opponent.hp==opponent.totalhp
  573. basedmg=(basedmg/2).floor
  574. end
  575. if isConst?(attacker.ability,PBAbilities,:HUGEPOWER)
  576. if isConst?(attacker.pokemon.ability,PBAbilities,:HUGEPOWER)
  577. atk*=2
  578. else
  579. atk=(atk*1.5).floor
  580. end
  581. end
  582. atk*=2 if isConst?(attacker.ability,PBAbilities,:PUREPOWER)
  583. atk=(atk*1.5).floor if isConst?(attacker.ability,PBAbilities,:HUSTLE)
  584. if isConst?(attacker.ability,PBAbilities,:GUTS) &&
  585. (attacker.status==PBStatuses::BURN ||
  586. attacker.status==PBStatuses::PARALYSIS ||
  587. attacker.status==PBStatuses::POISON)
  588. atk=(atk*1.5).floor
  589. end
  590. if (isConst?(attacker.ability,PBAbilities,:PLUS) ||
  591. isConst?(attacker.ability,PBAbilities,:MINUS))
  592. partner=attacker.pbPartner
  593. if partner && (isConst?(partner.ability,PBAbilities,:PLUS) ||
  594. isConst?(partner.ability,PBAbilities,:MINUS))
  595. spatk=(spatk*1.5).floor
  596. end
  597. end
  598. if isConst?(attacker.ability,PBAbilities,:FLASHFIRE) &&
  599. attacker.effects[PBEffects::FlashFire] && isConst?(type,PBTypes,:FIRE)
  600. basedmg=(basedmg*1.5).floor
  601. end
  602. if isConst?(opponent.ability,PBAbilities,:DRYSKIN) && isConst?(type,PBTypes,:FIRE)
  603. basedmg=(basedmg*1.25).floor
  604. end
  605. if isConst?(attacker.ability,PBAbilities,:RIVALRY) &&
  606. attacker.gender!=2 && opponent.gender!=2
  607. if attacker.gender==opponent.gender
  608. basedmg=(basedmg*1.25).floor
  609. else
  610. basedmg=(basedmg*0.75).floor
  611. end
  612. end
  613. if isConst?(attacker.ability,PBAbilities,:IRONFIST) &&
  614. (@flags&0x200)!=0 # flag j: Is punching move
  615. basedmg=(basedmg*1.2).floor
  616. end
  617. if isConst?(attacker.ability,PBAbilities,:RECKLESS)
  618. if @function==0xFA || # Take Down, etc.
  619. @function==0xFB || # Double-Edge, etc.
  620. @function==0xFC || # Head Smash
  621. @function==0xFD || # Volt Tackle
  622. @function==0xFE || # Flare Blitz
  623. @function==0x10B || # Jump Kick, Hi Jump Kick
  624. @function==0x130 # Shadow End
  625. basedmg=(basedmg*1.2).floor
  626. end
  627. end
  628. if isConst?(attacker.ability,PBAbilities,:SLOWSTART) && attacker.turncount<5
  629. atk=(atk/2).floor
  630. end
  631. if @battle.pbWeather==PBWeather::SUNNYDAY
  632. if isConst?(attacker.ability,PBAbilities,:SOLARPOWER)
  633. spatk=(spatk*1.5).floor
  634. end
  635. if isConst?(attacker.ability,PBAbilities,:FLOWERGIFT) ||
  636. isConst?(attacker.pbPartner.ability,PBAbilities,:FLOWERGIFT)
  637. atk=(atk*1.5).floor
  638. end
  639. if isConst?(opponent.ability,PBAbilities,:FLOWERGIFT) ||
  640. isConst?(opponent.pbPartner.ability,PBAbilities,:FLOWERGIFT)
  641. spdef=(spdef*1.5).floor
  642. end
  643. end
  644. if @battle.pbWeather==PBWeather::SANDSTORM
  645. if isConst?(attacker.ability,PBAbilities,:SANDFORCE) &&
  646. (isConst?(type,PBTypes,:ROCK) || isConst?(type,PBTypes,:GROUND) ||
  647. isConst?(type,PBTypes,:STEEL))
  648. basedmg=(basedmg*1.3).floor
  649. end
  650. end
  651. # Burns
  652. if attacker.status == PBStatuses::BURN &&
  653. !isConst?(attacker.ability,PBAbilities,:GUTS)
  654. atk=(atk/2).floor
  655. end
  656. if isConst?(attacker.ability,PBAbilities,:TOXICBOOST) && attacker.status==PBStatuses::POISON
  657. atk=(atk*1.5).floor
  658. end
  659. if isConst?(attacker.ability,PBAbilities,:FLAREBOOST) && attacker.status==PBStatuses::BURN
  660. spatk=(spatk*1.5).floor
  661. end
  662. if attacker.hp<=(attacker.totalhp/3).floor
  663. modbasedmg=(basedmg*1.5).floor
  664. basedmg=modbasedmg if isConst?(attacker.ability,PBAbilities,:OVERGROW) && isConst?(type,PBTypes,:GRASS)
  665. basedmg=modbasedmg if isConst?(attacker.ability,PBAbilities,:BLAZE) && isConst?(type,PBTypes,:FIRE)
  666. basedmg=modbasedmg if isConst?(attacker.ability,PBAbilities,:TORRENT) && isConst?(type,PBTypes,:WATER)
  667. basedmg=modbasedmg if isConst?(attacker.ability,PBAbilities,:SWARM) && isConst?(type,PBTypes,:BUG)
  668. end
  669. if isConst?(attacker.ability,PBAbilities,:DEFEATIST) &&
  670. attacker.hp<=(attacker.totalhp/2).floor
  671. atk=(atk/2).floor
  672. spatk=(spatk/2).floor
  673. end
  674. if isConst?(type,PBTypes,:ELECTRIC)
  675. for i in 0...4
  676. if @battle.battlers[i].effects[PBEffects::MudSport]
  677. basedmg=(basedmg/3).floor
  678. break # Not cumulative
  679. end
  680. end
  681. end
  682. if isConst?(type,PBTypes,:FIRE)
  683. for i in 0...4
  684. if @battle.battlers[i].effects[PBEffects::WaterSport]
  685. basedmg=(basedmg/3).floor
  686. break # Not cumulative
  687. end
  688. end
  689. end
  690. if isConst?(opponent.ability,PBAbilities,:THICKFAT) &&
  691. (isConst?(type,PBTypes,:ICE) || isConst?(type,PBTypes,:FIRE))
  692. basedmg=(basedmg/2).floor
  693. end
  694. if isConst?(opponent.ability,PBAbilities,:HEATPROOF) && isConst?(type,PBTypes,:FIRE)
  695. basedmg=(basedmg/2).floor
  696. end
  697. if isConst?(opponent.ability,PBAbilities,:TINTEDLENS) &&
  698. PBTypes.isNotVeryEffective?(type,opponent.type1,opponent.type2)
  699. basedmg=(basedmg*2)
  700. end
  701. if isConst?(opponent.ability,PBAbilities,:SNIPER) && opponent.damagestate.critical
  702. basedmg=(basedmg*1.5).floor
  703. end
  704. #Damage formula
  705. if type>=0 && pbIsSpecial?(type,attacker=nil)
  706. atk=spatk
  707. defense=spdef if @function!=0x122 # Psyshock
  708. end
  709. defense=1 if defense<1
  710. atk=1 if atk<1
  711. damage=(((2*attacker.level/5+2).floor*atk*basedmg/defense).floor/50).floor
  712. if pbTargetsAll?(attacker)
  713. damage=(damage*0.75).floor
  714. end
  715. #Weather
  716. weather=@battle.pbWeather
  717. if weather==PBWeather::SUNNYDAY
  718. if isConst?(type,PBTypes,:FIRE)
  719. damage=(damage*1.5).floor
  720. elsif isConst?(type,PBTypes,:WATER)
  721. damage>>=1
  722. end
  723. end
  724. if weather==PBWeather::RAINDANCE
  725. if isConst?(type,PBTypes,:WATER)
  726. damage=(damage*1.5).floor
  727. elsif isConst?(type,PBTypes,:FIRE)
  728. damage>>=1
  729. end
  730. end
  731. damage+=2
  732. if (options&IGNOREPKMNTYPES)==0
  733. #Same Type Attack Bonus
  734. if attacker.pbHasType?(type)
  735. if isConst?(attacker.ability,PBAbilities,:ADAPTABILITY)
  736. damage=(damage*2).floor
  737. else
  738. damage=(damage*1.5).floor
  739. end
  740. end
  741. #Type Effectiveness
  742. typemod=pbTypeModMessages(type,attacker,opponent)
  743. damage=(damage*typemod/4).floor
  744. opponent.damagestate.typemod=typemod
  745. if typemod==0
  746. opponent.damagestate.calcdamage=0
  747. opponent.damagestate.critical=false
  748. return 0
  749. end
  750. if typemod>4 # Super-effective
  751. if (isConst?(opponent.ability,PBAbilities,:SOLIDROCK) ||
  752. isConst?(opponent.ability,PBAbilities,:FILTER))
  753. damage=(damage*0.75).floor
  754. end
  755. if isConst?(attacker.item,PBItems,:EXPERTBELT)
  756. damage=(damage*1.2).floor
  757. end
  758. if (isConst?(opponent.item,PBItems,:CHOPLEBERRY) && isConst?(type,PBTypes,:FIGHTING)) ||
  759. (isConst?(opponent.item,PBItems,:COBABERRY) && isConst?(type,PBTypes,:FLYING)) ||
  760. (isConst?(opponent.item,PBItems,:KEBIABERRY) && isConst?(type,PBTypes,:POISON)) ||
  761. (isConst?(opponent.item,PBItems,:SHUCABERRY) && isConst?(type,PBTypes,:GROUND)) ||
  762. (isConst?(opponent.item,PBItems,:CHARTIBERRY) && isConst?(type,PBTypes,:ROCK)) ||
  763. (isConst?(opponent.item,PBItems,:TANGABERRY) && isConst?(type,PBTypes,:BUG)) ||
  764. (isConst?(opponent.item,PBItems,:KASIBBERRY) && isConst?(type,PBTypes,:GHOST)) ||
  765. (isConst?(opponent.item,PBItems,:BABIRIBERRY) && isConst?(type,PBTypes,:STEEL)) ||
  766. (isConst?(opponent.item,PBItems,:OCCABERRY) && isConst?(type,PBTypes,:FIRE)) ||
  767. (isConst?(opponent.item,PBItems,:PASSHOBERRY) && isConst?(type,PBTypes,:WATER)) ||
  768. (isConst?(opponent.item,PBItems,:RINDOBERRY) && isConst?(type,PBTypes,:GRASS)) ||
  769. (isConst?(opponent.item,PBItems,:WACANBERRY) && isConst?(type,PBTypes,:ELECTRIC)) ||
  770. (isConst?(opponent.item,PBItems,:PAYAPABERRY) && isConst?(type,PBTypes,:PSYCHIC)) ||
  771. (isConst?(opponent.item,PBItems,:YACHEBERRY) && isConst?(type,PBTypes,:ICE)) ||
  772. (isConst?(opponent.item,PBItems,:HABANBERRY) && isConst?(type,PBTypes,:DRAGON)) ||
  773. (isConst?(opponent.item,PBItems,:COLBURBERRY) && isConst?(type,PBTypes,:DARK))
  774. damage=(damage/2).floor
  775. opponent.pokemon.itemRecycle=opponent.item
  776. opponent.pokemon.itemInitial=0 if opponent.pokemon.itemInitial==opponent.item
  777. opponent.item=0
  778. end
  779. end
  780. if (isConst?(opponent.item,PBItems,:CHILANBERRY) && isConst?(type,PBTypes,:NORMAL))
  781. damage=(damage/2).floor
  782. opponent.pokemon.itemRecycle=opponent.item
  783. opponent.pokemon.itemInitial=0 if opponent.pokemon.itemInitial==opponent.item
  784. opponent.item=0
  785. end
  786. else
  787. opponent.damagestate.typemod=4
  788. end
  789. if isConst?(attacker.item,PBItems,:MUSCLEBAND) && pbIsPhysical?(type,attacker=nil)
  790. damage=(damage*1.1).floor
  791. end
  792. if isConst?(attacker.item,PBItems,:WISEGLASSES) && pbIsSpecial?(type,attacker=nil)
  793. damage=(damage*1.1).floor
  794. end
  795. damage=pbModifyDamage(damage,attacker,opponent)
  796. # Charge
  797. if attacker.effects[PBEffects::Charge]>0 && isConst?(type,PBTypes,:ELECTRIC)
  798. damage=(damage*2).floor
  799. end
  800. if !opponent.damagestate.critical && (options&NOREFLECT)==0 &&
  801. !isConst?(attacker.ability,PBAbilities,:INFILTRATOR)
  802. #Reflect
  803. oppside=opponent.pbOwnSide
  804. if oppside.effects[PBEffects::Reflect]>0 && pbIsPhysical?(type,attacker=nil)
  805. # if opponent has a partner [TODO: should apply even if partner faints during an attack]
  806. if opponent.pbPartner.hp>0
  807. damage=(damage*2/3).floor
  808. else
  809. damage=(damage/2).floor
  810. end
  811. end
  812. #Light Screen
  813. if oppside.effects[PBEffects::LightScreen]>0 && pbIsSpecial?(type,attacker=nil)
  814. # if opponent has a partner [TODO: should apply even if partner faints during an attack]
  815. if opponent.pbPartner.hp>0
  816. damage=(damage*2/3).floor
  817. else
  818. damage=(damage/2).floor
  819. end
  820. end
  821. end
  822. #Damage weighting
  823. if (options&NOWEIGHTING)==0
  824. random=85+@battle.pbRandom(16)
  825. damage=(damage*random/100).floor
  826. end
  827. if opponent.damagestate.critical
  828. damage*=2
  829. end
  830. damage=1 if damage<1
  831. opponent.damagestate.calcdamage=damage
  832. return damage
  833. end
  834.  
  835. def pbModifyDamage(damage,attacker,opponent)
  836. return damage
  837. end
  838.  
  839. def pbReduceHPDamage(damage,attacker,opponent)
  840. endure=false
  841. if opponent.effects[PBEffects::Substitute]>0 && (!attacker || attacker.index!=opponent.index)
  842. damage=opponent.effects[PBEffects::Substitute] if damage>opponent.effects[PBEffects::Substitute]
  843. opponent.effects[PBEffects::Substitute]-=damage
  844. opponent.damagestate.substitute=true
  845. @battle.scene.pbDamageAnimation(opponent,0)
  846. @battle.pbDisplayPaused(_INTL("The SUBSTITUTE took damage for {1}!",opponent.name))
  847. if opponent.effects[PBEffects::Substitute]<=0
  848. opponent.effects[PBEffects::Substitute]=0
  849. @battle.pbDisplayPaused(_INTL("{1}'s SUBSTITUTE faded!",opponent.name))
  850. end
  851. opponent.damagestate.hplost=damage
  852. damage=0
  853. else
  854. if damage>=opponent.hp
  855. damage=opponent.hp
  856. if @function==0xE9 # False Swipe
  857. damage=damage-1
  858. elsif opponent.effects[PBEffects::Endure]
  859. damage=damage-1
  860. opponent.damagestate.endured=true
  861. elsif isConst?(opponent.ability,PBAbilities,:STURDY) && damage==opponent.totalhp
  862. opponent.damagestate.sturdy=true
  863. damage=damage-1
  864. elsif opponent.damagestate.focussash && damage==opponent.totalhp
  865. opponent.damagestate.focussashused=true
  866. damage=damage-1
  867. opponent.pokemon.itemRecycle=opponent.item
  868. opponent.pokemon.itemInitial=0 if opponent.pokemon.itemInitial==opponent.item
  869. opponent.item=0
  870. elsif opponent.damagestate.focusband
  871. opponent.damagestate.focusbandused=true
  872. damage=damage-1
  873. end
  874. damage=0 if damage<0
  875. end
  876. oldhp=opponent.hp
  877. opponent.hp-=damage
  878. effectiveness=0
  879. if opponent.damagestate.typemod<4
  880. effectiveness=1 # "Not very effective"
  881. elsif opponent.damagestate.typemod>4
  882. effectiveness=2 # "Super effective"
  883. end
  884. if opponent.damagestate.typemod!=0
  885. @battle.scene.pbDamageAnimation(opponent,effectiveness)
  886. end
  887. @battle.scene.pbHPChanged(opponent,oldhp)
  888. opponent.damagestate.hplost=damage
  889. end
  890. return damage
  891. end
  892.  
  893. ################################################################################
  894. # Effects
  895. ################################################################################
  896. def pbEffectMessages(attacker,opponent,ignoretype=false)
  897. if opponent.damagestate.critical
  898. @battle.pbDisplay(_INTL("A critical hit!"))
  899. end
  900. if !pbIsMultiHit
  901. if opponent.damagestate.typemod>4
  902. @battle.pbDisplay(_INTL("It's super effective!"))
  903. elsif opponent.damagestate.typemod>=1 && opponent.damagestate.typemod<4
  904. @battle.pbDisplay(_INTL("It's not very effective..."))
  905. end
  906. end
  907. if opponent.damagestate.endured
  908. @battle.pbDisplay(_INTL("{1} endured the hit!",opponent.pbThis))
  909. elsif opponent.damagestate.sturdy
  910. @battle.pbDisplay(_INTL("{1} hung on with STURDY!",opponent.pbThis))
  911. elsif opponent.damagestate.focussashused
  912. @battle.pbDisplay(_INTL("{1} hung on using its FOCUS SASH!",opponent.pbThis))
  913. elsif opponent.damagestate.focusbandused
  914. @battle.pbDisplay(_INTL("{1} hung on using its FOCUS BAND!",opponent.pbThis))
  915. end
  916. if opponent.damagestate.hplost>=1 && !opponent.damagestate.substitute
  917. if !ignoretype
  918. movetype=pbType(@type,attacker,opponent)
  919. if isConst?(opponent.ability,PBAbilities,:ANGERPOINT)
  920. if opponent.pbCanIncreaseStatStage?(PBStats::ATTACK) &&
  921. opponent.damagestate.critical
  922. opponent.stages[PBStats::ATTACK]=6
  923. @battle.pbCommonAnimation("StatUp",opponent,nil)
  924. @battle.pbDisplay(_INTL("{1}'s {2} maxed its ATTACK!",
  925. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  926. end
  927. end
  928. if isConst?(opponent.ability,PBAbilities,:JUSTIFIED) &&
  929. isConst?(movetype,PBTypes,:DARK)
  930. if opponent.pbCanIncreaseStatStage?(PBStats::ATTACK)
  931. opponent.pbIncreaseStatBasic(PBStats::ATTACK,1)
  932. @battle.pbCommonAnimation("StatUp",opponent,nil)
  933. @battle.pbDisplay(_INTL("{1}'s {2} raised its ATTACK!",
  934. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  935. end
  936. end
  937. if isConst?(opponent.ability,PBAbilities,:RATTLED) &&
  938. (isConst?(movetype,PBTypes,:BUG) ||
  939. isConst?(movetype,PBTypes,:DARK) ||
  940. isConst?(movetype,PBTypes,:GHOST))
  941. if opponent.pbCanIncreaseStatStage?(PBStats::SPEED)
  942. opponent.pbIncreaseStatBasic(PBStats::SPEED,1)
  943. @battle.pbCommonAnimation("StatUp",opponent,nil)
  944. @battle.pbDisplay(_INTL("{1}'s {2} raised its SPEED!",
  945. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  946. end
  947. end
  948. if isConst?(opponent.ability,PBAbilities,:WEAKARMOR) && pbIsPhysical?(type,attacker=nil,movetype)
  949. if opponent.pbCanReduceStatStage?(PBStats::DEFENSE,false,true)
  950. opponent.pbReduceStatBasic(PBStats::DEFENSE,1)
  951. @battle.pbCommonAnimation("StatDown",opponent,nil)
  952. @battle.pbDisplay(_INTL("{1}'s {2} lowered its DEFENSE!",
  953. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  954. end
  955. if opponent.pbCanIncreaseStatStage?(PBStats::SPEED)
  956. opponent.pbIncreaseStatBasic(PBStats::SPEED,1)
  957. @battle.pbCommonAnimation("StatUp",opponent,nil)
  958. @battle.pbDisplay(_INTL("{1}'s {2} raised its SPEED!",
  959. opponent.pbThis,PBAbilities.getName(opponent.ability)))
  960. end
  961. end
  962. if isConst?(opponent.item,PBItems,:ABSORBBULB) &&
  963. isConst?(movetype,PBTypes,:WATER)
  964. if opponent.pbCanIncreaseStatStage?(PBStats::SPATK)
  965. opponent.pbIncreaseStatBasic(PBStats::SPATK,1)
  966. @battle.pbCommonAnimation("StatUp",opponent,nil)
  967. @battle.pbDisplay(_INTL("{1}'s {2} raised its SP. ATTACK!",
  968. opponent.pbThis,PBItems.getName(opponent.item)))
  969. opponent.pokemon.itemRecycle=opponent.item
  970. opponent.pokemon.itemInitial=0 if opponent.pokemon.itemInitial==opponent.item
  971. opponent.item=0
  972. end
  973. end
  974. if isConst?(opponent.item,PBItems,:CELLBATTERY) &&
  975. isConst?(movetype,PBTypes,:ELECTRIC)
  976. if opponent.pbCanIncreaseStatStage?(PBStats::ATTACK)
  977. opponent.pbIncreaseStatBasic(PBStats::ATTACK,1)
  978. @battle.pbCommonAnimation("StatUp",opponent,nil)
  979. @battle.pbDisplay(_INTL("{1}'s {2} raised its ATTACK!",
  980. opponent.pbThis,PBItems.getName(opponent.item)))
  981. opponent.pokemon.itemRecycle=opponent.item
  982. opponent.pokemon.itemInitial=0 if opponent.pokemon.itemInitial==opponent.item
  983. opponent.item=0
  984. end
  985. end
  986. end
  987. if isConst?(opponent.item,PBItems,:AIRBALLOON)
  988. opponent.pokemon.itemRecycle=opponent.item
  989. opponent.pokemon.itemInitial=0 if opponent.pokemon.itemInitial==opponent.item
  990. opponent.item=0
  991. @battle.pbDisplay(_INTL("{1}'s AIR BALLOON burst!",opponent.pbThis))
  992. end
  993. end
  994. end
  995.  
  996. def pbEffectFixedDamage(damage,attacker,opponent,hitnum=0,alltargets=nil,showanimation=true)
  997. type=@type
  998. type=pbType(type,attacker,opponent)
  999. typemod=pbTypeModMessages(type,attacker,opponent)
  1000. opponent.damagestate.critical=false
  1001. opponent.damagestate.typemod=0
  1002. opponent.damagestate.calcdamage=0
  1003. opponent.damagestate.hplost=0
  1004. if typemod!=0
  1005. opponent.damagestate.calcdamage=damage
  1006. opponent.damagestate.typemod=4
  1007. pbShowAnimation(@id,attacker,opponent,hitnum,alltargets,showanimation)
  1008. damage=1 if damage<1 # HP reduced can't be less than 1
  1009. damage=pbReduceHPDamage(damage,attacker,opponent)
  1010. pbEffectMessages(attacker,opponent)
  1011. pbOnDamageLost(damage,attacker,opponent)
  1012. return damage
  1013. end
  1014. return 0
  1015. end
  1016.  
  1017. def pbEffect(attacker,opponent,hitnum=0,alltargets=nil,showanimation=true)
  1018. return 0 if !opponent
  1019. damage=pbCalcDamage(attacker,opponent)
  1020. if opponent.damagestate.typemod!=0
  1021. pbShowAnimation(@id,attacker,opponent,hitnum,alltargets,showanimation)
  1022. end
  1023. damage=pbReduceHPDamage(damage,attacker,opponent)
  1024. pbEffectMessages(attacker,opponent)
  1025. pbOnDamageLost(damage,attacker,opponent)
  1026. return damage # The HP lost by the opponent due to this attack
  1027. end
  1028.  
  1029. ################################################################################
  1030. # Using the move
  1031. ################################################################################
  1032. def pbOnStartUse(attacker)
  1033. return true
  1034. end
  1035.  
  1036. def pbAddTarget(targets,attacker)
  1037. end
  1038.  
  1039. def pbSuccessCheck(attacker,opponent,numtargets)
  1040. end
  1041.  
  1042. def pbDisplayUseMessage(attacker)
  1043. # Return values:
  1044. # -1 if the attack should exit as a failure
  1045. # 1 if the attack should exit as a success
  1046. # 0 if the attack should proceed its effect
  1047. # 2 if Bide is storing energy
  1048. @battle.pbDisplayBrief(_INTL("{1} used {2}!",attacker.pbThis,name))
  1049. return 0
  1050. end
  1051.  
  1052. def pbShowAnimation(id,attacker,opponent,hitnum=0,alltargets=nil,showanimation=true)
  1053. return if !showanimation
  1054. @battle.pbAnimation(id,attacker,opponent,hitnum)
  1055. end
  1056.  
  1057. def pbOnDamageLost(damage,attacker,opponent)
  1058. #Used by Counter/Mirror Coat/Revenge/Focus Punch/Bide
  1059. type=@type
  1060. type=pbType(type,attacker,opponent)
  1061. if opponent.effects[PBEffects::Bide]>0
  1062. opponent.effects[PBEffects::BideDamage]+=damage
  1063. opponent.effects[PBEffects::BideTarget]=attacker.index
  1064. end
  1065. if @function==90 # Hidden Power
  1066. type=getConst(PBTypes,:NORMAL) || 0
  1067. end
  1068. if pbIsPhysical?(type,attacker=nil)
  1069. opponent.effects[PBEffects::Counter]=damage
  1070. opponent.effects[PBEffects::CounterTarget]=attacker.index
  1071. end
  1072. if pbIsSpecial?(type,attacker=nil)
  1073. opponent.effects[PBEffects::MirrorCoat]=damage
  1074. opponent.effects[PBEffects::MirrorCoatTarget]=attacker.index
  1075. end
  1076. opponent.lastHPLost=damage # for Revenge/Focus Punch/Metal Burst
  1077. opponent.lastAttacker=attacker.index # for Revenge/Metal Burst
  1078. end
  1079.  
  1080. def pbMoveFailed(attacker,opponent)
  1081. # Called to determine whether the move failed
  1082. return false
  1083. end
  1084. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement