3 changed files with 581 additions and 0 deletions
@ -0,0 +1,450 @@ |
|||
import sys |
|||
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QListWidget, QLineEdit, |
|||
QLabel, QCheckBox, QPushButton, QFormLayout, QListWidgetItem, QSplitter, QTreeWidget, |
|||
QTreeWidgetItem, QDialog, QDialogButtonBox, QComboBox, QMessageBox) |
|||
from PyQt6.QtCore import Qt, QSize |
|||
from PyQt6.QtGui import QPixmap, QFontMetrics, QColor |
|||
import sqlite3 |
|||
import json |
|||
import os |
|||
|
|||
class EvolutionEditDialog(QDialog): |
|||
def __init__(self, parent=None, from_pfic=None, to_pfic=None, method=None): |
|||
super().__init__(parent) |
|||
self.setWindowTitle("Edit Evolution") |
|||
self.setModal(True) |
|||
|
|||
layout = QVBoxLayout(self) |
|||
|
|||
self.from_combo = QComboBox() |
|||
self.to_combo = QComboBox() |
|||
self.method_edit = QLineEdit(method) |
|||
|
|||
layout.addWidget(QLabel("From Pokémon:")) |
|||
layout.addWidget(self.from_combo) |
|||
layout.addWidget(QLabel("To Pokémon:")) |
|||
layout.addWidget(self.to_combo) |
|||
layout.addWidget(QLabel("Evolution Method:")) |
|||
layout.addWidget(self.method_edit) |
|||
|
|||
self.button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) |
|||
self.button_box.accepted.connect(self.accept) |
|||
self.button_box.rejected.connect(self.reject) |
|||
layout.addWidget(self.button_box) |
|||
|
|||
self.delete_button = QPushButton("Delete Evolution") |
|||
self.delete_button.clicked.connect(self.delete_evolution) |
|||
layout.addWidget(self.delete_button) |
|||
|
|||
self.populate_combos(from_pfic, to_pfic) |
|||
|
|||
def populate_combos(self, from_pfic, to_pfic): |
|||
cursor = self.parent().cursor |
|||
cursor.execute('SELECT PFIC, name, form_name FROM pokemon_forms ORDER BY name, form_name') |
|||
for pfic, name, form_name in cursor.fetchall(): |
|||
display_name = f"{name} ({form_name})" if form_name else name |
|||
self.from_combo.addItem(display_name, pfic) |
|||
self.to_combo.addItem(display_name, pfic) |
|||
|
|||
if from_pfic: |
|||
self.from_combo.setCurrentIndex(self.from_combo.findData(from_pfic)) |
|||
if to_pfic: |
|||
self.to_combo.setCurrentIndex(self.to_combo.findData(to_pfic)) |
|||
|
|||
def delete_evolution(self): |
|||
self.done(2) # Use a custom return code for delete action |
|||
|
|||
class DBEditor(QMainWindow): |
|||
def __init__(self): |
|||
super().__init__() |
|||
self.setWindowTitle("Pokémon Database Editor") |
|||
self.setGeometry(100, 100, 1000, 600) |
|||
|
|||
self.conn = sqlite3.connect(':memory:') # Use in-memory database for runtime |
|||
self.cursor = self.conn.cursor() |
|||
self.init_database() |
|||
self.patches = self.load_and_apply_patches() |
|||
|
|||
self.init_ui() |
|||
|
|||
def init_database(self): |
|||
# Copy the original database to the in-memory database |
|||
disk_conn = sqlite3.connect('pokemon_forms.db') |
|||
disk_conn.backup(self.conn) |
|||
disk_conn.close() |
|||
|
|||
def load_and_apply_patches(self): |
|||
try: |
|||
with open('patches.json', 'r') as f: |
|||
patches = json.load(f) |
|||
except FileNotFoundError: |
|||
patches = {} |
|||
|
|||
# Apply patches to the in-memory database |
|||
for patch_key, patch in patches.items(): |
|||
if patch_key.startswith('evolution_'): |
|||
from_pfic, to_pfic = patch_key.split('_')[1:] |
|||
if patch['action'] == 'delete': |
|||
self.cursor.execute(''' |
|||
DELETE FROM evolution_chains |
|||
WHERE from_pfic = ? AND to_pfic = ? |
|||
''', (from_pfic, to_pfic)) |
|||
elif patch['action'] == 'update': |
|||
self.cursor.execute(''' |
|||
UPDATE evolution_chains |
|||
SET from_pfic = ?, to_pfic = ?, method = ? |
|||
WHERE from_pfic = ? AND to_pfic = ? |
|||
''', (patch['new_from_pfic'], patch['new_to_pfic'], patch['new_method'], from_pfic, to_pfic)) |
|||
elif patch['action'] == 'add': |
|||
self.cursor.execute(''' |
|||
INSERT OR REPLACE INTO evolution_chains (from_pfic, to_pfic, method) |
|||
VALUES (?, ?, ?) |
|||
''', (patch['from_pfic'], patch['to_pfic'], patch['method'])) |
|||
else: # pokemon_storage patches |
|||
self.cursor.execute(''' |
|||
UPDATE pokemon_storage |
|||
SET storable_in_home = ? |
|||
WHERE PFIC = ? |
|||
''', (patch['storable_in_home'], patch_key)) |
|||
|
|||
self.conn.commit() |
|||
return patches |
|||
|
|||
def save_patches(self): |
|||
with open('patches.json', 'w') as f: |
|||
json.dump(self.patches, f) |
|||
|
|||
def init_ui(self): |
|||
central_widget = QWidget() |
|||
self.setCentralWidget(central_widget) |
|||
main_layout = QHBoxLayout(central_widget) |
|||
|
|||
# Left side: Search and List |
|||
left_layout = QVBoxLayout() |
|||
self.search_bar = QLineEdit() |
|||
self.search_bar.setPlaceholderText("Search Pokémon...") |
|||
self.search_bar.textChanged.connect(self.filter_pokemon_list) |
|||
left_layout.addWidget(self.search_bar) |
|||
|
|||
self.pokemon_list = QListWidget() |
|||
self.pokemon_list.currentItemChanged.connect(self.load_pokemon_details) |
|||
left_layout.addWidget(self.pokemon_list) |
|||
|
|||
# Right side: Edit panel |
|||
right_layout = QHBoxLayout() |
|||
|
|||
# Left side of right panel: Text information |
|||
text_layout = QVBoxLayout() |
|||
self.edit_form = QFormLayout() |
|||
self.name_label = QLabel() |
|||
self.form_name_label = QLabel() |
|||
self.national_dex_label = QLabel() |
|||
self.generation_label = QLabel() |
|||
self.home_checkbox = QCheckBox("Available in Home") |
|||
|
|||
self.edit_form.addRow("Name:", self.name_label) |
|||
self.edit_form.addRow("Form:", self.form_name_label) |
|||
self.edit_form.addRow("National Dex:", self.national_dex_label) |
|||
self.edit_form.addRow("Generation:", self.generation_label) |
|||
self.edit_form.addRow(self.home_checkbox) |
|||
|
|||
text_layout.addLayout(self.edit_form) |
|||
|
|||
# Evolution chain tree |
|||
self.evolution_tree = QTreeWidget() |
|||
self.evolution_tree.setHeaderLabels(["Pokémon", "Evolution Method"]) |
|||
self.evolution_tree.setColumnWidth(0, 200) |
|||
text_layout.addWidget(self.evolution_tree) |
|||
|
|||
# Move buttons to the bottom |
|||
text_layout.addStretch(1) |
|||
|
|||
self.save_button = QPushButton("Save Changes") |
|||
self.save_button.clicked.connect(self.save_changes) |
|||
text_layout.addWidget(self.save_button) |
|||
|
|||
self.export_button = QPushButton("Export Database") |
|||
self.export_button.clicked.connect(self.export_database) |
|||
text_layout.addWidget(self.export_button) |
|||
|
|||
# Add New Evolution button |
|||
self.add_evolution_button = QPushButton("Add New Evolution") |
|||
self.add_evolution_button.clicked.connect(self.add_new_evolution) |
|||
text_layout.addWidget(self.add_evolution_button) |
|||
|
|||
# Right side of right panel: Image |
|||
image_layout = QVBoxLayout() |
|||
self.image_label = QLabel() |
|||
self.image_label.setAlignment(Qt.AlignmentFlag.AlignCenter) |
|||
self.image_label.setFixedSize(200, 200) |
|||
image_layout.addWidget(self.image_label) |
|||
image_layout.addStretch(1) |
|||
|
|||
right_layout.addLayout(text_layout) |
|||
right_layout.addLayout(image_layout) |
|||
|
|||
main_layout.addLayout(left_layout, 1) |
|||
main_layout.addLayout(right_layout, 1) |
|||
|
|||
self.load_pokemon_list() |
|||
self.adjust_list_width() |
|||
|
|||
def adjust_list_width(self): |
|||
max_width = 0 |
|||
font_metrics = QFontMetrics(self.pokemon_list.font()) |
|||
for i in range(self.pokemon_list.count()): |
|||
item_width = font_metrics.horizontalAdvance(self.pokemon_list.item(i).text()) |
|||
max_width = max(max_width, item_width) |
|||
|
|||
# Add some padding to the width |
|||
list_width = max_width + 50 |
|||
self.pokemon_list.setFixedWidth(list_width) |
|||
self.search_bar.setFixedWidth(list_width) |
|||
|
|||
def load_pokemon_list(self): |
|||
self.cursor.execute(''' |
|||
SELECT pf.PFIC, pf.name, pf.form_name, pf.national_dex |
|||
FROM pokemon_forms pf |
|||
ORDER BY pf.national_dex, pf.form_name |
|||
''') |
|||
pokemon_data = self.cursor.fetchall() |
|||
|
|||
for pfic, name, form_name, national_dex in pokemon_data: |
|||
display_name = f"{national_dex:04d} - {name}" |
|||
if form_name: |
|||
display_name += f" ({form_name})" |
|||
item = QListWidgetItem(display_name) |
|||
item.setData(Qt.ItemDataRole.UserRole, pfic) |
|||
self.pokemon_list.addItem(item) |
|||
|
|||
def filter_pokemon_list(self): |
|||
search_text = self.search_bar.text().lower() |
|||
for i in range(self.pokemon_list.count()): |
|||
item = self.pokemon_list.item(i) |
|||
item.setHidden(search_text not in item.text().lower()) |
|||
|
|||
def load_pokemon_details(self, current, previous): |
|||
if not current: |
|||
return |
|||
|
|||
pfic = current.data(Qt.ItemDataRole.UserRole) |
|||
self.cursor.execute(''' |
|||
SELECT pf.name, pf.form_name, pf.national_dex, pf.generation, ps.storable_in_home |
|||
FROM pokemon_forms pf |
|||
LEFT JOIN pokemon_storage ps ON pf.PFIC = ps.PFIC |
|||
WHERE pf.PFIC = ? |
|||
''', (pfic,)) |
|||
pokemon_data = self.cursor.fetchone() |
|||
|
|||
if pokemon_data: |
|||
name, form_name, national_dex, generation, storable_in_home = pokemon_data |
|||
self.name_label.setText(name) |
|||
self.form_name_label.setText(form_name if form_name else "") |
|||
self.national_dex_label.setText(str(national_dex)) |
|||
self.generation_label.setText(str(generation)) |
|||
self.home_checkbox.setChecked(bool(storable_in_home)) |
|||
|
|||
# Load and display the image |
|||
image_path = f"images-new/{pfic}.png" |
|||
if os.path.exists(image_path): |
|||
pixmap = QPixmap(image_path) |
|||
self.image_label.setPixmap(pixmap.scaled(200, 200, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)) |
|||
else: |
|||
self.image_label.setText("Image not found") |
|||
|
|||
# Load and display evolution chain |
|||
self.load_evolution_chain(pfic) |
|||
|
|||
self.current_pfic = pfic |
|||
self.add_evolution_button.setEnabled(True) # Enable the button when a Pokémon is selected |
|||
|
|||
def edit_evolution(self, item, column): |
|||
parent = item.parent() |
|||
if not parent: |
|||
return # Don't edit the root item |
|||
|
|||
from_pfic = parent.data(0, Qt.ItemDataRole.UserRole) |
|||
to_pfic = item.data(0, Qt.ItemDataRole.UserRole) |
|||
method = item.text(1) |
|||
|
|||
dialog = EvolutionEditDialog(self, from_pfic, to_pfic, method) |
|||
result = dialog.exec() |
|||
|
|||
if result == QDialog.DialogCode.Accepted: |
|||
new_from_pfic = dialog.from_combo.currentData() |
|||
new_to_pfic = dialog.to_combo.currentData() |
|||
new_method = dialog.method_edit.text() |
|||
|
|||
# Update the in-memory database |
|||
self.cursor.execute(''' |
|||
UPDATE evolution_chains |
|||
SET from_pfic = ?, to_pfic = ?, method = ? |
|||
WHERE from_pfic = ? AND to_pfic = ? |
|||
''', (new_from_pfic, new_to_pfic, new_method, from_pfic, to_pfic)) |
|||
|
|||
# Create or update the patch |
|||
patch_key = f"evolution_{from_pfic}_{to_pfic}" |
|||
self.patches[patch_key] = { |
|||
'action': 'update', |
|||
'new_from_pfic': new_from_pfic, |
|||
'new_to_pfic': new_to_pfic, |
|||
'new_method': new_method |
|||
} |
|||
self.save_patches() |
|||
|
|||
# Refresh the evolution chain display |
|||
self.load_evolution_chain(self.current_pfic) |
|||
|
|||
elif result == 2: # Delete action |
|||
confirm = QMessageBox.question(self, "Confirm Deletion", "Are you sure you want to delete this evolution?", |
|||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) |
|||
if confirm == QMessageBox.StandardButton.Yes: |
|||
# Delete from the in-memory database |
|||
self.cursor.execute(''' |
|||
DELETE FROM evolution_chains |
|||
WHERE from_pfic = ? AND to_pfic = ? |
|||
''', (from_pfic, to_pfic)) |
|||
|
|||
# Create a delete patch |
|||
patch_key = f"evolution_{from_pfic}_{to_pfic}" |
|||
self.patches[patch_key] = {'action': 'delete'} |
|||
self.save_patches() |
|||
|
|||
# Refresh the evolution chain display |
|||
self.load_evolution_chain(self.current_pfic) |
|||
|
|||
def get_evolution_chain(self, pfic): |
|||
def follow_chain(start_pfic, visited=None): |
|||
if visited is None: |
|||
visited = set() |
|||
|
|||
chain = [] |
|||
stack = [(start_pfic, None)] |
|||
|
|||
while stack: |
|||
current_pfic, method = stack.pop() |
|||
if current_pfic in visited: |
|||
continue |
|||
|
|||
visited.add(current_pfic) |
|||
self.cursor.execute('SELECT name, form_name FROM pokemon_forms WHERE PFIC = ?', (current_pfic,)) |
|||
name, form_name = self.cursor.fetchone() |
|||
|
|||
chain.append((current_pfic, name, form_name, method)) |
|||
|
|||
# Get previous evolutions |
|||
self.cursor.execute('SELECT from_pfic, method FROM evolution_chains WHERE to_pfic = ?', (current_pfic,)) |
|||
prev_evolutions = self.cursor.fetchall() |
|||
for prev_pfic, prev_method in prev_evolutions: |
|||
if prev_pfic not in visited: |
|||
stack.append((prev_pfic, prev_method)) |
|||
|
|||
# Get next evolutions |
|||
self.cursor.execute('SELECT to_pfic, method FROM evolution_chains WHERE from_pfic = ?', (current_pfic,)) |
|||
next_evolutions = self.cursor.fetchall() |
|||
for next_pfic, next_method in next_evolutions: |
|||
if next_pfic not in visited: |
|||
stack.append((next_pfic, next_method)) |
|||
|
|||
return chain |
|||
|
|||
return follow_chain(pfic) |
|||
|
|||
def load_evolution_chain(self, pfic): |
|||
self.evolution_tree.clear() |
|||
evolution_chain = self.get_evolution_chain(pfic) |
|||
|
|||
# Create a dictionary to store tree items |
|||
tree_items = {} |
|||
|
|||
# First pass: create all tree items |
|||
for current_pfic, name, form_name, method in evolution_chain: |
|||
display_name = f"{name} ({form_name})" if form_name else name |
|||
item = QTreeWidgetItem([display_name, method if method else ""]) |
|||
item.setData(0, Qt.ItemDataRole.UserRole, current_pfic) |
|||
tree_items[current_pfic] = item |
|||
|
|||
if current_pfic == pfic: |
|||
item.setBackground(0, QColor(255, 255, 0, 100)) # Highlight selected Pokémon |
|||
|
|||
# Second pass: build the tree structure |
|||
root = None |
|||
for current_pfic, name, form_name, method in evolution_chain: |
|||
item = tree_items[current_pfic] |
|||
|
|||
# Find the parent of this item |
|||
self.cursor.execute('SELECT from_pfic FROM evolution_chains WHERE to_pfic = ?', (current_pfic,)) |
|||
parent_pfic = self.cursor.fetchone() |
|||
|
|||
if parent_pfic: |
|||
parent_item = tree_items.get(parent_pfic[0]) |
|||
if parent_item: |
|||
parent_item.addChild(item) |
|||
elif not root: |
|||
root = item |
|||
self.evolution_tree.addTopLevelItem(root) |
|||
|
|||
# Expand the entire tree |
|||
self.evolution_tree.expandAll() |
|||
|
|||
# Scroll to and select the current Pokémon |
|||
current_item = tree_items[pfic] |
|||
self.evolution_tree.scrollToItem(current_item) |
|||
self.evolution_tree.setCurrentItem(current_item) |
|||
|
|||
# Connect double-click signal |
|||
self.evolution_tree.itemDoubleClicked.connect(self.edit_evolution) |
|||
|
|||
def save_changes(self): |
|||
if hasattr(self, 'current_pfic'): |
|||
storable_in_home = self.home_checkbox.isChecked() |
|||
self.patches[self.current_pfic] = {'storable_in_home': storable_in_home} |
|||
|
|||
with open('patches.json', 'w') as f: |
|||
json.dump(self.patches, f) |
|||
|
|||
def export_database(self): |
|||
export_conn = sqlite3.connect('pokemon_forms_production.db') |
|||
self.conn.backup(export_conn) |
|||
export_conn.close() |
|||
|
|||
def closeEvent(self, event): |
|||
self.conn.close() |
|||
event.accept() |
|||
|
|||
def add_new_evolution(self): |
|||
if not hasattr(self, 'current_pfic'): |
|||
return |
|||
|
|||
dialog = EvolutionEditDialog(self, self.current_pfic, None, "") |
|||
result = dialog.exec() |
|||
|
|||
if result == QDialog.DialogCode.Accepted: |
|||
new_from_pfic = dialog.from_combo.currentData() |
|||
new_to_pfic = dialog.to_combo.currentData() |
|||
new_method = dialog.method_edit.text() |
|||
|
|||
# Update the in-memory database |
|||
self.cursor.execute(''' |
|||
INSERT INTO evolution_chains (from_pfic, to_pfic, method) |
|||
VALUES (?, ?, ?) |
|||
''', (new_from_pfic, new_to_pfic, new_method)) |
|||
|
|||
# Create a new patch |
|||
patch_key = f"evolution_{new_from_pfic}_{new_to_pfic}" |
|||
self.patches[patch_key] = { |
|||
'action': 'add', |
|||
'from_pfic': new_from_pfic, |
|||
'to_pfic': new_to_pfic, |
|||
'method': new_method |
|||
} |
|||
self.save_patches() |
|||
|
|||
# Refresh the evolution chain display |
|||
self.load_evolution_chain(self.current_pfic) |
|||
|
|||
if __name__ == '__main__': |
|||
app = QApplication(sys.argv) |
|||
editor = DBEditor() |
|||
editor.show() |
|||
sys.exit(app.exec()) |
|||
@ -0,0 +1,131 @@ |
|||
{ |
|||
"evolution_0019-01-000-2_0020-01-001-0": { |
|||
"action": "delete" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-001-0": { |
|||
"action": "update", |
|||
"new_from_pfic": "0868-08-000-0", |
|||
"new_to_pfic": "0869-08-001-0", |
|||
"new_method": "Spin clockwise for more than 5 seconds during the day while holding a Berry Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-002-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-002-0", |
|||
"method": "Spin clockwise for more than 5 seconds during the day while holding a Clover Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-003-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-003-0", |
|||
"method": "Spin clockwise for more than 5 seconds during the day while holding a Flower Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-004-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-004-0", |
|||
"method": "Spin clockwise for more than 5 seconds during the day while holding a Love Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-005-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-005-0", |
|||
"method": "Spin clockwise for more than 5 seconds during the day while holding a Ribbon Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-006-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-006-0", |
|||
"method": "Spin clockwise for more than 5 seconds during the day while holding a Star Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-007-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-007-0", |
|||
"method": "Spin clockwise for more than 5 seconds during the day while holding a Strawberry Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-008-0": { |
|||
"action": "update", |
|||
"new_from_pfic": "0868-08-000-0", |
|||
"new_to_pfic": "0869-08-008-0", |
|||
"new_method": "Spin clockwise for more than 5 seconds at night while holding a Berry Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-009-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-009-0", |
|||
"method": "Spin clockwise for more than 5 seconds at night while holding a Clover Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-010-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-010-0", |
|||
"method": "Spin clockwise for more than 5 seconds at night while holding a Flower Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-011-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-011-0", |
|||
"method": "Spin clockwise for more than 5 seconds at night while holding a Love Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-012-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-012-0", |
|||
"method": "Spin clockwise for more than 5 seconds at night while holding a Ribbon Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-013-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-013-0", |
|||
"method": "Spin clockwise for more than 5 seconds at night while holding a Star Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-014-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-014-0", |
|||
"method": "Spin clockwise for more than 5 seconds at night while holding a Strawberry Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-016-0": { |
|||
"action": "update", |
|||
"new_from_pfic": "0868-08-000-0", |
|||
"new_to_pfic": "0869-08-016-0", |
|||
"new_method": "Spin clockwise for less than 5 seconds at night while holding a Berry Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-017-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-017-0", |
|||
"method": "Spin clockwise for less than 5 seconds at night while holding a Clover Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-018-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-018-0", |
|||
"method": "Spin clockwise for less than 5 seconds at night while holding a Flower Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-019-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-019-0", |
|||
"method": "Spin clockwise for less than 5 seconds at night while holding a Love Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-020-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-020-0", |
|||
"method": "Spin clockwise for less than 5 seconds at night while holding a Ribbon Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-021-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-021-0", |
|||
"method": "Spin clockwise for less than 5 seconds at night while holding a Star Sweet \u2192" |
|||
}, |
|||
"evolution_0868-08-000-0_0869-08-022-0": { |
|||
"action": "add", |
|||
"from_pfic": "0868-08-000-0", |
|||
"to_pfic": "0869-08-022-0", |
|||
"method": "Spin clockwise for less than 5 seconds at night while holding a Strawberry Sweet \u2192" |
|||
} |
|||
} |
|||
Binary file not shown.
Loading…
Reference in new issue