1
1
from typing import TextIO
2
2
import os
3
3
import logging
4
+ from copy import deepcopy
4
5
5
6
from BaseClasses import Item , MultiWorld , Tutorial , ItemClassification
6
7
from Fill import fill_restrictive , FillError , sweep_from_pool
@@ -62,6 +63,8 @@ def __init__(self, world: MultiWorld, player: int):
62
63
self .learnsets = None
63
64
self .trainer_name = None
64
65
self .rival_name = None
66
+ self .type_chart = None
67
+ self .traps = None
65
68
66
69
@classmethod
67
70
def stage_assert_generate (cls , world ):
@@ -108,6 +111,69 @@ def encode_name(name, t):
108
111
109
112
process_pokemon_data (self )
110
113
114
+ if self .multiworld .randomize_type_chart [self .player ] == "vanilla" :
115
+ chart = deepcopy (poke_data .type_chart )
116
+ elif self .multiworld .randomize_type_chart [self .player ] == "randomize" :
117
+ types = poke_data .type_names .values ()
118
+ matchups = []
119
+ for type1 in types :
120
+ for type2 in types :
121
+ matchups .append ([type1 , type2 ])
122
+ self .multiworld .random .shuffle (matchups )
123
+ immunities = self .multiworld .immunity_matchups [self .player ].value
124
+ super_effectives = self .multiworld .super_effective_matchups [self .player ].value
125
+ not_very_effectives = self .multiworld .not_very_effective_matchups [self .player ].value
126
+ normals = self .multiworld .normal_matchups [self .player ].value
127
+ while super_effectives + not_very_effectives + normals < 225 - immunities :
128
+ super_effectives += self .multiworld .super_effective_matchups [self .player ].value
129
+ not_very_effectives += self .multiworld .not_very_effective_matchups [self .player ].value
130
+ normals += self .multiworld .normal_matchups [self .player ].value
131
+ if super_effectives + not_very_effectives + normals > 225 - immunities :
132
+ total = super_effectives + not_very_effectives + normals
133
+ excess = total - (225 - immunities )
134
+ subtract_amounts = (
135
+ int ((excess / (super_effectives + not_very_effectives + normals )) * super_effectives ),
136
+ int ((excess / (super_effectives + not_very_effectives + normals )) * not_very_effectives ),
137
+ int ((excess / (super_effectives + not_very_effectives + normals )) * normals ))
138
+ super_effectives -= subtract_amounts [0 ]
139
+ not_very_effectives -= subtract_amounts [1 ]
140
+ normals -= subtract_amounts [2 ]
141
+ while super_effectives + not_very_effectives + normals > 225 - immunities :
142
+ r = self .multiworld .random .randint (0 , 2 )
143
+ if r == 0 :
144
+ super_effectives -= 1
145
+ elif r == 1 :
146
+ not_very_effectives -= 1
147
+ else :
148
+ normals -= 1
149
+ chart = []
150
+ for matchup_list , matchup_value in zip ([immunities , normals , super_effectives , not_very_effectives ],
151
+ [0 , 10 , 20 , 5 ]):
152
+ for _ in range (matchup_list ):
153
+ matchup = matchups .pop ()
154
+ matchup .append (matchup_value )
155
+ chart .append (matchup )
156
+ elif self .multiworld .randomize_type_chart [self .player ] == "chaos" :
157
+ types = poke_data .type_names .values ()
158
+ matchups = []
159
+ for type1 in types :
160
+ for type2 in types :
161
+ matchups .append ([type1 , type2 ])
162
+ chart = []
163
+ values = list (range (21 ))
164
+ self .multiworld .random .shuffle (matchups )
165
+ self .multiworld .random .shuffle (values )
166
+ for matchup in matchups :
167
+ value = values .pop (0 )
168
+ values .append (value )
169
+ matchup .append (value )
170
+ chart .append (matchup )
171
+ # sort so that super-effective matchups occur first, to prevent dual "not very effective" / "super effective"
172
+ # matchups from leading to damage being ultimately divided by 2 and then multiplied by 2, which can lead to
173
+ # damage being reduced by 1 which leads to a "not very effective" message appearing due to my changes
174
+ # to the way effectiveness messages are generated.
175
+ self .type_chart = sorted (chart , key = lambda matchup : - matchup [2 ])
176
+
111
177
def create_items (self ) -> None :
112
178
start_inventory = self .multiworld .start_inventory [self .player ].value .copy ()
113
179
if self .multiworld .randomize_pokedex [self .player ] == "start_with" :
@@ -128,8 +194,7 @@ def create_items(self) -> None:
128
194
item = self .create_item (location .original_item )
129
195
if (item .classification == ItemClassification .filler and self .multiworld .random .randint (1 , 100 )
130
196
<= self .multiworld .trap_percentage [self .player ].value ):
131
- item = self .create_item (self .multiworld .random .choice ([item for item in item_table if
132
- item_table [item ].classification == ItemClassification .trap ]))
197
+ item = self .create_item (self .select_trap ())
133
198
if location .event :
134
199
self .multiworld .get_location (location .name , self .player ).place_locked_item (item )
135
200
elif "Badge" not in item .name or self .multiworld .badgesanity [self .player ].value :
@@ -255,13 +320,21 @@ def write_spoiler(self, spoiler_handle):
255
320
256
321
def get_filler_item_name (self ) -> str :
257
322
if self .multiworld .random .randint (1 , 100 ) <= self .multiworld .trap_percentage [self .player ].value :
258
- return self .multiworld .random .choice ([item for item in item_table if
259
- item_table [item ].classification == ItemClassification .trap ])
323
+ return self .select_trap ()
260
324
261
325
return self .multiworld .random .choice ([item for item in item_table if item_table [
262
326
item ].classification == ItemClassification .filler and item not in item_groups ["Vending Machine Drinks" ] +
263
327
item_groups ["Unique" ]])
264
328
329
+ def select_trap (self ):
330
+ if self .traps is None :
331
+ self .traps = []
332
+ self .traps += ["Poison Trap" ] * self .multiworld .poison_trap_weight [self .player ].value
333
+ self .traps += ["Fire Trap" ] * self .multiworld .fire_trap_weight [self .player ].value
334
+ self .traps += ["Paralyze Trap" ] * self .multiworld .paralyze_trap_weight [self .player ].value
335
+ self .traps += ["Ice Trap" ] * self .multiworld .ice_trap_weight [self .player ].value
336
+ return self .multiworld .random .choice (self .traps )
337
+
265
338
def fill_slot_data (self ) -> dict :
266
339
return {
267
340
"second_fossil_check_condition" : self .multiworld .second_fossil_check_condition [self .player ].value ,
0 commit comments