-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmisc.rb
More file actions
111 lines (91 loc) · 3.19 KB
/
Copy pathmisc.rb
File metadata and controls
111 lines (91 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
require './pokemon'
require './entityloader'
module PokeSky
IMMUNITY_ABILITIES = {
'Levitate' => 'Ground',
'Water Absorb' => 'Water',
'Fire Absorb' => 'Fire',
'Volt Absorb' => 'Electric',
'Sap Sipper' => 'Grass'
}
# Return the Pokemon game, given an ID.
# TODO: The performance of Hash#keys *might* be bad. Check doc sometime.
def name_for_id(id)
@el.expr['pokemon'].keys[id - 1]
end
# Calculate the move power for a move.
def move_power(move)
@el.expr['attacks'].each do |type, attacks|
if attacks.include?(move)
idx = @el.expr['attacks'][type].index(move)
idx /= 2.0 if type == 'Normal'
return ((120 * Math.log10((idx + 1).to_f / 2 + 1)) + 1).ceil # 170
end
end
end
# Return the move type of a move.
def move_type(move)
@el.expr['attacks'].each do |type, attacks|
return type if attacks.include?(move)
end
end
# Return the ID of a type.
def type_id(type)
@el.expr['types'].index(type)
end
# Calculate the basic single type multiplier.
def type_multiplier(atk_type, def_type)
mul = @el.expr['type_x'][atk_type][type_id(def_type)]
# Handle inverse battles.
@modes.include?(:inverse) ? 1.0 / (mul.zero? ? 0.5 : mul) : mul
end
# Calculate the attack multiplier of a move, given the attack type
# and the two types of the defending Pokemon.
def attack_multiplier(atk_type, def_prim, def_sec)
mul = type_multiplier(atk_type, def_prim)
mul *= type_multiplier(atk_type, def_sec) if def_sec
mul
end
# Calculate attack bonus, given a Pokemon's level.
def attack_bonus(lv)
(110 * 3 * lv.to_f + 250) / 100 + 5
end
# Calculate defense bonus, given a Pokemon's level.
def defense_bonus(lv)
(80 * 3 * lv.to_f / 2 + 250) / 100 + 5
end
# Check whether the defending Pokemon has an ability that will
# make it immune to the attack.
def immune_from_ability?(move, defender)
IMMUNITY_ABILITIES.each do |ability, type|
in_grp = @el.expr['abilities'][ability].include?(defender.id)
mv_has_type = type == move_type(move)
return true if in_grp && mv_has_type
end
false
end
# Calculate the damage for a given move and attacking and defending Pokemon.
def calculate_hit(move, attacker, defender)
type = move_type(move)
base_pwr = move_power(move)
atk_mul = attack_multiplier(type, defender.type.prim, defender.type.sec)
stab = (type == attacker.type.prim || type == attacker.type.sec) ? 1.5 : 1
# TODO: Critical hits.
cr = 1
atk_bonus = attack_bonus(attacker.level)
def_bonus = defense_bonus(defender.level)
r = rand(85...100) / 100.0
mod = stab * atk_mul * cr * r
# base_dmg = (((attacker.level * 2 / 5.0 + 2) *
# base_pwr * atk_bonus / 50 / def_bonus + 2) *
# cr * r / 100 * stab * atk_mul)
base_dmg = ((2 * attacker.level + 10) / 250.0 *
(atk_bonus / def_bonus) * base_pwr + 2) * mod
# TOOD: Check levitate, fire absorb, water absorb, volt absorb,
# sap sipper, etc.
return 0 if immune_from_ability?(move, defender)
# Handle wonderguard mode.
return 0 unless atk_mul > 1 if @modes.include?(:wonderguard)
base_dmg.round
end
end