Release candidate
BIN
Resources/Icon/LogoGoppier.ico
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 133 B After Width: | Height: | Size: 133 B |
|
Before Width: | Height: | Size: 4.6 MiB After Width: | Height: | Size: 4.6 MiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
283
feebasCalcs.py
@@ -1,133 +1,285 @@
|
||||
"""
|
||||
feebasCalcs.py
|
||||
|
||||
This file serves as the starting point for the Finding Feebas application.
|
||||
It initialises the interface and has functions for all interactions, like moving the map,
|
||||
pressing buttons and checking the input on the entry boxes.
|
||||
"""
|
||||
|
||||
from tkinter import ttk
|
||||
from tkinter import *
|
||||
|
||||
from trendyPhrase import group_conditions, group_lifestyles, group_hobbies, DewfordTrend
|
||||
from feebasCoordinates import FEEBAS_COORDINATES
|
||||
|
||||
DEBUG_ENABLED = False
|
||||
|
||||
class FeebasCalculator:
|
||||
def __init__(self, trainer_id, lottery_number, trendy_phrase_1, trendy_phrase_2, is_rs):
|
||||
"""
|
||||
This class calculates the exact spots of where Feebas is located based on the Trainer ID, the Lottery Number and the Trendy Phrase.
|
||||
This class can only find Feebas if a new game has started without a working battery.
|
||||
"""
|
||||
def __init__(self, trainer_id, lottery_number, trendy_phrase_1, trendy_phrase_2, is_emerald):
|
||||
"""
|
||||
This function initialises AND calculates the Feebas spots based on the parameters given.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
trainer_id: The Trainer ID of the player
|
||||
lottery_number: The Lottery Number found in Lilicove City
|
||||
trendy_phrase_1: The first word of the Trendy Phrase found in Dewford Town
|
||||
trendy_phrase_2: The second word of the Trendy Phrase found in Dewford Town
|
||||
is_emerald: A boolean indicating if these values are from Ruby/Sapphire (False) or Emerald (True)
|
||||
"""
|
||||
|
||||
self.is_feebas_found = False
|
||||
self.feebas_seed = 0
|
||||
|
||||
# Checks to make sure the values given are correct
|
||||
if not((trendy_phrase_1 in group_conditions) and ((trendy_phrase_2 in group_lifestyles) or (trendy_phrase_2 in group_hobbies))):
|
||||
return
|
||||
if(trainer_id == '' or lottery_number == ''):
|
||||
return
|
||||
|
||||
# Initialises the values of the Feebas calculator
|
||||
self.trainer_id = int(trainer_id)
|
||||
self.secret_id = 0
|
||||
self.secret_ids = []
|
||||
self.lottery_number = int(lottery_number)
|
||||
self.trendy_phrase_1 = trendy_phrase_1
|
||||
self.trendy_phrase_2 = trendy_phrase_2
|
||||
self.starting_seeds = []
|
||||
self.calculated_feebas_spots = []
|
||||
self.rng_counter = 0
|
||||
self.vblank = 0xFFFFFFFF
|
||||
|
||||
if(is_rs):
|
||||
|
||||
# Initialise the RNG based on which game is used for the calculator
|
||||
if(is_emerald == False):
|
||||
self.seedRng(0x5A0)
|
||||
else:
|
||||
self.seedRng(self.trainer_id)
|
||||
|
||||
|
||||
# Find the RNG starting point for the Feebas calculation
|
||||
self.findFeebasStartingPoint()
|
||||
for x in self.starting_seeds:
|
||||
self.findFeebasSpotsEmerald(x)
|
||||
|
||||
# Calculate the Trendy Phrase
|
||||
for seed in self.starting_seeds:
|
||||
if(is_emerald == False):
|
||||
self.findTrendyPhraseRubySapphire(seed)
|
||||
else:
|
||||
self.findTrendyPhraseEmerald(seed)
|
||||
|
||||
if(self.is_feebas_found == True):
|
||||
break
|
||||
|
||||
# Return if no Feebas seed was found
|
||||
if(self.is_feebas_found == False):
|
||||
print("FUCK")
|
||||
return
|
||||
|
||||
# Seed the RNG with the value found for the Trendy Phrase
|
||||
self.seedRng(self.feebas_seed)
|
||||
|
||||
self.seedRng(self.dewford_trends[0].getRandomValue())
|
||||
|
||||
# Calculate the actual Feebas spots
|
||||
x = 0
|
||||
while(x != 6):
|
||||
feebas_id = self.getFeebasRandomValue() % 447
|
||||
feebas_id = self.getRandomValue() % 447
|
||||
if(feebas_id == 0):
|
||||
feebas_id = 447
|
||||
if(feebas_id >= 4):
|
||||
self.calculated_feebas_spots.append(FEEBAS_COORDINATES[feebas_id])
|
||||
x += 1
|
||||
|
||||
return
|
||||
|
||||
|
||||
def isFeebasFound(self):
|
||||
"""
|
||||
This function indicates if the class has found the Feebas spots or not
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
Returns:
|
||||
self.is_feebas_found: A boolean indicating if the class has found the Feebas spots
|
||||
"""
|
||||
return self.is_feebas_found
|
||||
|
||||
def getSecretIds(self):
|
||||
return self.secret_ids
|
||||
|
||||
def getFeebasSpotCoordinates(self):
|
||||
"""
|
||||
This function returns the calculated Feebas spots
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
Returns:
|
||||
self.calculated_feebas_spots: An array containing the 6 Feebas spot coordinates
|
||||
"""
|
||||
return self.calculated_feebas_spots
|
||||
#return FEEBAS_COORDINATES
|
||||
|
||||
|
||||
def seedRng(self, seed):
|
||||
"""
|
||||
This function seeds the local RNG function with any 32 bit seed
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
seed: A 32 bit value containing the seed for the RNG
|
||||
"""
|
||||
self.random_value = seed & 0xFFFFFFFF
|
||||
|
||||
def getFeebasRandomValue(self):
|
||||
self.random_value = 0x41C64E6D * self.random_value + 0x00003039
|
||||
self.random_value &= 0xFFFFFFFF
|
||||
return (self.random_value >> 16)
|
||||
|
||||
def getRandomValue(self):
|
||||
"""
|
||||
This function progresses the RNG once and returns the newly generated value
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
Returns:
|
||||
self.random_value: The upper 16 bits of the randomly generated value.
|
||||
"""
|
||||
self.random_value = 0x41C64E6D * self.random_value + 0x00006073
|
||||
self.random_value &= 0xFFFFFFFF
|
||||
self.rng_counter += 1
|
||||
if(self.vblank == self.rng_counter):
|
||||
self.random_value = 0x41C64E6D * self.random_value + 0x00006073
|
||||
self.random_value &= 0xFFFFFFFF
|
||||
self.rng_counter += 1
|
||||
print(self.vblank)
|
||||
return (self.random_value >> 16)
|
||||
|
||||
def getPreviousRandomValue(self):
|
||||
"""
|
||||
This function calculates the previous RNG value and returns it
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
Returns:
|
||||
self.random_value: The upper 16 bits of the previous random value.
|
||||
"""
|
||||
self.random_value = 0xEEB9EB65 * self.random_value + 0x0A3561A1;
|
||||
self.random_value &= 0xFFFFFFFF
|
||||
return (self.random_value >> 16)
|
||||
|
||||
def findFeebasStartingPoint(self):
|
||||
"""
|
||||
This function finds the starting point for the Trendy Phrase calculation based on the Lottory Number. It does this by progressing the RNG
|
||||
20000 frames (around 5,5 minutes) forward and saves all moments the RNG generated the given Lottory Number in an array.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
"""
|
||||
|
||||
self.starting_seeds = []
|
||||
for x in range(20000):
|
||||
random_value = self.getRandomValue()
|
||||
if(random_value == self.lottery_number):
|
||||
self.starting_seeds.append(self.random_value)
|
||||
print(self.starting_seeds)
|
||||
|
||||
def findFeebasSpotsRubySapphire(self, lottery_seed):
|
||||
def findTrendyPhraseRubySapphire(self, lottery_seed):
|
||||
"""
|
||||
This function generates the dewford phrases for Ruby and Sapphire based on the lottory seed that was found before. It first find the starting
|
||||
point using the Trainer ID. Afterwards the Dewford Phrases are generated. If the last RNG call made ends with the Lottory Number and the Trendiest
|
||||
Phrase matches, then Feebas is found successfully!
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
lottery_seed: The seed of the RNG which generated the Lottory Number
|
||||
"""
|
||||
lottery_no = 0
|
||||
final_trendy_prase = ["NO", "FEEBAS"]
|
||||
|
||||
# Seed the RNG and regress backwards a total of 50 RNG calls maximum or until the Trainer ID is found.
|
||||
self.seedRng(lottery_seed)
|
||||
self.rng_counter = 0
|
||||
for x in range(50):
|
||||
self.getPreviousRandomValue()
|
||||
# if((self.random_value >> 16) == self.trainer_id)
|
||||
def findFeebasSpotsEmerald(self, lottery_seed):
|
||||
prev_rng_value = self.getPreviousRandomValue()
|
||||
if(prev_rng_value == self.trainer_id):
|
||||
break
|
||||
# Nothing is found, return back
|
||||
if(x == 50):
|
||||
return
|
||||
# Trainer ID is found! Time to calculate the rest of the values
|
||||
# First we do one more step backwards for the Secret ID
|
||||
temp_secret_id = self.getPreviousRandomValue()
|
||||
|
||||
# 3 RNG calls before the dewford phrases
|
||||
self.getRandomValue()
|
||||
self.getRandomValue()
|
||||
self.getRandomValue()
|
||||
|
||||
# Generate the 5 dewford phrases
|
||||
self.generateDewfordPhrases()
|
||||
final_trendy_prase = self.dewford_trends[0].getPhrase()
|
||||
|
||||
# Generate the lottory number
|
||||
lottery_no = self.getRandomValue()
|
||||
|
||||
# Check all the values. If it all matches, then Feebas is found!!
|
||||
if((self.lottery_number == lottery_no) and (final_trendy_prase[0] == self.trendy_phrase_1 and final_trendy_prase[1] == self.trendy_phrase_2)):
|
||||
if(DEBUG_ENABLED == True):
|
||||
print("FOUND!!!!!")
|
||||
print("Secret ID:" + str(temp_secret_id))
|
||||
print("Feebas Seed:" + str(self.dewford_trends[0].getRandomValue()))
|
||||
self.secret_ids.append(temp_secret_id)
|
||||
self.is_feebas_found = True
|
||||
self.feebas_seed = self.dewford_trends[0].getRandomValue()
|
||||
|
||||
def findTrendyPhraseEmerald(self, lottery_seed):
|
||||
"""
|
||||
This function generates the dewford phrases for Ruby and Sapphire based on the lottory seed that was found before. Emerald doesn't have a clear
|
||||
starting point, so we need to regress a variable amount of time until we Trendy Phrase and the Lottory ID matches up. If this happens, then we have
|
||||
found Feebas successfully! It also tries to find the Secret ID, but it is possible however to find more than one Secret ID...
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
lottery_seed: The seed of the RNG which generated the Lottory Number
|
||||
"""
|
||||
|
||||
reverse_steps = 50
|
||||
lottery_no = 0
|
||||
final_trendy_prase = ["NO", "FEEBAS"]
|
||||
while((self.lottery_number != lottery_no) or (final_trendy_prase[0] != self.trendy_phrase_1 or final_trendy_prase[1] != self.trendy_phrase_2)):
|
||||
|
||||
for steps in range(20):
|
||||
self.seedRng(lottery_seed)
|
||||
#print(lottery_seed)
|
||||
self.rng_counter = 0
|
||||
for x in range(reverse_steps):
|
||||
for x in range(reverse_steps - steps):
|
||||
self.getPreviousRandomValue()
|
||||
|
||||
# First the Secret ID is generated
|
||||
temp_secret_id = self.getRandomValue()
|
||||
|
||||
# 3 RNG calls before the dewford phrases
|
||||
self.getRandomValue()
|
||||
self.getRandomValue()
|
||||
self.getRandomValue()
|
||||
|
||||
# Generate the 5 dewford phrases
|
||||
self.generateDewfordPhrases()
|
||||
|
||||
final_trendy_prase = self.dewford_trends[0].getPhrase()
|
||||
|
||||
# Generate the lottory number
|
||||
lottery_no = self.getRandomValue()
|
||||
|
||||
reverse_steps -= 1
|
||||
if(reverse_steps < 30):
|
||||
print("UGH")
|
||||
return
|
||||
print("FOUND!!!!!")
|
||||
print(self.dewford_trends[0].getRandomValue())
|
||||
self.is_feebas_found = True
|
||||
|
||||
# Check all the values. If it all matches, then Feebas is found!!
|
||||
if((self.lottery_number == lottery_no) and (final_trendy_prase[0] == self.trendy_phrase_1 and final_trendy_prase[1] == self.trendy_phrase_2)):
|
||||
if(DEBUG_ENABLED == True):
|
||||
print("FOUND!!!!!")
|
||||
print("Secret ID:" + str(temp_secret_id))
|
||||
print("Feebas Seed:" + str(self.dewford_trends[0].getRandomValue()))
|
||||
print("Reverse Steps:" + str(reverse_steps - steps))
|
||||
self.secret_ids.append(temp_secret_id)
|
||||
self.is_feebas_found = True
|
||||
self.feebas_seed = self.dewford_trends[0].getRandomValue()
|
||||
|
||||
|
||||
def generateDewfordPhrases(self):
|
||||
"""
|
||||
This function generates 5 Dewford Phrases and sorts them based on their Trendiness.
|
||||
This is a direct copy of how the game does it as well.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
"""
|
||||
|
||||
self.dewford_trends = []
|
||||
for x in range(5):
|
||||
new_trend = DewfordTrend()
|
||||
|
||||
# Generate the phrase
|
||||
phrase_1 = group_conditions[self.getRandomValue() % len(group_conditions)]
|
||||
if(self.getRandomValue() & 1 == 1):
|
||||
phrase_2 = group_lifestyles[self.getRandomValue() % len(group_lifestyles)]
|
||||
else:
|
||||
phrase_2 = group_hobbies[self.getRandomValue() % len(group_hobbies)]
|
||||
new_trend.setPhrase(phrase_1, phrase_2)
|
||||
#print(phrase_1)
|
||||
|
||||
# Generate the Trendiness values and the Random value
|
||||
new_trend.setIsGainingTrendiness(self.getRandomValue() & 1)
|
||||
|
||||
rando = self.getRandomValue() % 98
|
||||
@@ -141,10 +293,18 @@ class FeebasCalculator:
|
||||
new_trend.setRandomValue(self.getRandomValue())
|
||||
|
||||
self.dewford_trends.append(new_trend)
|
||||
|
||||
# Sort the trends based on their Trendiness values
|
||||
self.sortTrends()
|
||||
|
||||
|
||||
def sortTrends(self):
|
||||
"""
|
||||
This function sorts the 5 Dewford Phrases based on their Trendiness values
|
||||
This is a direct copy of how the game does it as well.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
"""
|
||||
for x in range(5):
|
||||
y = x + 1
|
||||
while(y < 5):
|
||||
@@ -153,6 +313,15 @@ class FeebasCalculator:
|
||||
y += 1
|
||||
|
||||
def compareTrends(self, a, b):
|
||||
"""
|
||||
This function compares two trends in order to see which one has a higher Trendiness value.
|
||||
This is a direct copy of how the game does it as well.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
a: A dewford trend index
|
||||
b: A dewford trend index
|
||||
"""
|
||||
if(self.dewford_trends[a].getTrendiness() > self.dewford_trends[b].getTrendiness()):
|
||||
return True
|
||||
if(self.dewford_trends[a].getTrendiness() < self.dewford_trends[b].getTrendiness()):
|
||||
@@ -164,6 +333,16 @@ class FeebasCalculator:
|
||||
|
||||
return (self.getRandomValue() & 1)
|
||||
|
||||
def SWAP(self, list, pos1, pos2):
|
||||
list[pos1], list[pos2] = list[pos2], list[pos1]
|
||||
return list
|
||||
def SWAP(self, dewford_list, pos1, pos2):
|
||||
"""
|
||||
This function swaps two trends with each other in the dewford_list
|
||||
This is a direct copy of how the game does it as well.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
dewford_list: The 5 dewford trends in a list
|
||||
pos1: Index of a Dewford trend that is to be swapped with pos2
|
||||
pos2: Index of a Dewford trend that is to be swapped with pos1
|
||||
"""
|
||||
dewford_list[pos1], dewford_list[pos2] = dewford_list[pos2], dewford_list[pos1]
|
||||
return dewford_list
|
||||
|
||||
539
main.py
@@ -1,239 +1,340 @@
|
||||
"""
|
||||
main.py
|
||||
|
||||
This file serves as the starting point for the Finding Feebas application.
|
||||
It initialises the interface and has functions for all interactions, like moving the map,
|
||||
pressing buttons and checking the input on the entry boxes.
|
||||
"""
|
||||
|
||||
from feebasCalcs import FeebasCalculator
|
||||
from trendyPhrase import group_conditions, group_lifestyles, group_hobbies
|
||||
|
||||
from tkinter import ttk
|
||||
from tkinter import *
|
||||
from ttkwidgets.autocomplete import AutocompleteCombobox
|
||||
from feebasCalcs import FeebasCalculator
|
||||
|
||||
from trendyPhrase import group_conditions, group_lifestyles, group_hobbies
|
||||
|
||||
# pip install pillow
|
||||
from PIL import Image, ImageTk
|
||||
|
||||
ROUTE119_PATH = "./Resources/Images/Hoenn_Route_119_E.png"
|
||||
FINDING_FEEBAS_ART = "./Resources/Images/Finding_Feebas_BG.jpg"
|
||||
FEEBAS_SPOT_INDICATOR = "./Resources/Images/Feebas_Spot_Indicator.png"
|
||||
ROUTE119_INITAL_X_POS = 192
|
||||
ROUTE119_INITAL_Y_POS = 960
|
||||
HACKY_FEEBAS_BUTTON_INIT = [0, 1, 2, 3, 4, 5]
|
||||
|
||||
class Route119:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.canvas = Canvas(self.root, width=320, height=560, bg="white")
|
||||
image = Image.open('./Recources/Hoenn_Route_119_E.png')
|
||||
self.render = ImageTk.PhotoImage(image)
|
||||
img = self.canvas.create_image(192, 960, image=self.render)
|
||||
self.canvas.place(relx=0.25,rely=0.5,anchor=CENTER)
|
||||
"""
|
||||
This class handles the entire interface and all possible inputs made by the user.
|
||||
"""
|
||||
def __init__(self, root):
|
||||
"""
|
||||
This function initialises the entire interface of the application.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
root: The root of the tkinter Finding Feebas Application
|
||||
"""
|
||||
self.root = root
|
||||
|
||||
# Initialise the map on the left
|
||||
self.map_canvas = Canvas(self.root, width=320, height=560, bg="white")
|
||||
image = Image.open(ROUTE119_PATH)
|
||||
self.map_render = ImageTk.PhotoImage(image)
|
||||
self.map_canvas.create_image(ROUTE119_INITAL_X_POS, ROUTE119_INITAL_Y_POS, image=self.map_render)
|
||||
self.map_canvas.place(relx=0.25,rely=0.5,anchor=CENTER)
|
||||
|
||||
# Initialise the art on the right
|
||||
self.art_canvas = Canvas(self.root, width=320, height=560, bg="white")
|
||||
image = Image.open(FINDING_FEEBAS_ART)
|
||||
resized_image= image.resize((325,565))
|
||||
self.art_render = ImageTk.PhotoImage(resized_image)
|
||||
self.art_canvas.create_image(160, 280, image=self.art_render)
|
||||
self.art_canvas.place(relx=0.75,rely=0.5,anchor=CENTER)
|
||||
|
||||
# Initialise the current position of the map and mouse position
|
||||
self.current_image_xpos = ROUTE119_INITAL_X_POS
|
||||
self.current_image_ypos = ROUTE119_INITAL_Y_POS
|
||||
self.current_mouse_xpos = 0
|
||||
self.current_mouse_ypos = 0
|
||||
self.map_canvas.bind('<Button-1>', self.mousePressCanvas)
|
||||
self.map_canvas.bind("<B1-Motion>", self.mouseMove)
|
||||
|
||||
# Initialise the checkbox for Ruby/Sapphire and Emerald. It is coded so that a variable will be 1 if Emerald is selected.
|
||||
self.is_emerald = IntVar()
|
||||
self.is_emerald.set(0)
|
||||
ruby_sapphire_checkbox = ttk.Checkbutton(self.root, text='Ruby/Sapphire',variable=self.is_emerald, onvalue=0, offvalue=1)
|
||||
ruby_sapphire_checkbox.place(x=320*0.55/2+320, y=150, anchor="center")
|
||||
emerald_checkbox = ttk.Checkbutton(self.root, text='Emerald',variable=self.is_emerald, onvalue=1, offvalue=0)
|
||||
emerald_checkbox.place(x=320*1.45/2+320, y=150, anchor="center")
|
||||
|
||||
# Initialise the label and entry box for the Trainder ID and the Lottery ID
|
||||
validate_command_function = (self.root.register(self.validateNumber), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
|
||||
|
||||
tid_label = ttk.Label(root, text='Trainer ID')
|
||||
tid_label.place(x=320*1.5/7+320, y=200, anchor="w")
|
||||
|
||||
sv = StringVar()
|
||||
sv.trace("w", lambda name, index, mode, sv=sv: self.maxNumberCallback(sv, 0xFFFF, 0))
|
||||
self.tid_entry = ttk.Entry(root, validate="key", validatecommand=validate_command_function, textvariable=sv, width=10)
|
||||
self.tid_entry.place(x=320*3.5/7+320, y=200, anchor="w")
|
||||
|
||||
lot_label = ttk.Label(root, text='Lottery No.')
|
||||
lot_label.place(x=320*1.5/7+320, y=225, anchor="w")
|
||||
|
||||
sv = StringVar()
|
||||
sv.trace("w", lambda name, index, mode, sv=sv: self.maxNumberCallback(sv, 0xFFFF, 1))
|
||||
self.lot_enrty = ttk.Entry(root, validate="key", validatecommand=validate_command_function, textvariable=sv, width=10)
|
||||
self.lot_enrty.place(x=320*3.5/7+320, y=225, anchor="w")
|
||||
|
||||
self.canvas2 = Canvas(self.root, width=320, height=560, bg="white")
|
||||
image = Image.open('./Recources/Finding_Feebas_BG.jpg')
|
||||
resized_image= image.resize((325,565))
|
||||
self.render2 = ImageTk.PhotoImage(resized_image)
|
||||
img = self.canvas2.create_image(160, 280, image=self.render2)
|
||||
self.canvas2.place(relx=0.75,rely=0.5,anchor=CENTER)
|
||||
|
||||
self.current_image_xpos = 192
|
||||
self.current_image_ypos = 960
|
||||
# Initialise the lists for the trendhy phrase and place them in a dropdown menu
|
||||
self.trendy_phrase_1 = group_conditions.copy()
|
||||
self.trendy_phrase_1.sort()
|
||||
|
||||
self.trendy_phrase_2 = group_lifestyles + group_hobbies
|
||||
self.trendy_phrase_2.sort()
|
||||
|
||||
self.drop1 = AutocompleteCombobox(root, completevalues=self.trendy_phrase_1)
|
||||
self.drop1.place(x=320*0.55/2+320, y=360, anchor="center")
|
||||
self.drop1.config(width = 17)
|
||||
|
||||
self.drop2 = AutocompleteCombobox(root, completevalues=self.trendy_phrase_2)
|
||||
self.drop2.place(x=320*1.45/2+320, y=360, anchor="center")
|
||||
self.drop2.config(width = 17)
|
||||
|
||||
# Initialise the buttons to calculate and clear the feebas spots
|
||||
calculate_button = ttk.Button(root, text='Calculate', command=self.calculateFeebasSpots, state= NORMAL)
|
||||
calculate_button.place(x=320*2/7+320, y=410, anchor="center")
|
||||
clear_button = ttk.Button(root, text='Clear', command=self.clearFeebasSpots, state= NORMAL)
|
||||
clear_button.place(x=320*5/7+320, y=410, anchor="center")
|
||||
|
||||
# Initialise label and unusable entry box for Secret ID
|
||||
secret_id_label = ttk.Label(root, text='Secret ID:')
|
||||
secret_id_label.place(x=320*1.2/7+320, y=455, anchor="center")
|
||||
|
||||
self.secret_id_entry = ttk.Label(root, text='')
|
||||
self.secret_id_entry.place(x=320*4.15/7+320, y=455, anchor="center")
|
||||
self.secret_id_entry.config(background='#c5cedb')
|
||||
self.secret_id_entry.config(width = 33)
|
||||
|
||||
# Initialise the 6 buttons to find the feebas spots in the map.
|
||||
self.feebas_spot_buttons = []
|
||||
|
||||
spot_button = ttk.Button(root, text='1', command= lambda: self.goToFeebasSpot(0), state= DISABLED, width=4)
|
||||
spot_button.place(x=320/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='2', command= lambda: self.goToFeebasSpot(1), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*2/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='3', command= lambda: self.goToFeebasSpot(2), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*3/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='4', command= lambda: self.goToFeebasSpot(3), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*4/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
self.current_mouse_xpos = 0
|
||||
self.current_mouse_ypos = 0
|
||||
|
||||
self.canvas.bind('<Button-1>', self.mousePressCanvas)
|
||||
self.canvas.bind("<B1-Motion>", self.mouseMove)
|
||||
spot_button = ttk.Button(root, text='5', command= lambda: self.goToFeebasSpot(4), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*5/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='6', command= lambda: self.goToFeebasSpot(5), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*6/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
self.trendy_1 = group_conditions.copy()
|
||||
self.trendy_1.sort()
|
||||
|
||||
self.trendy_2 = group_lifestyles + group_hobbies
|
||||
self.trendy_2.sort()
|
||||
|
||||
self.var = IntVar()
|
||||
self.var.set(1)
|
||||
self.ruby_sapphire_checkbox = ttk.Checkbutton(self.root, text='Ruby/Sapphire',variable=self.var, onvalue=1, offvalue=0, command=self.rs_selected)
|
||||
self.ruby_sapphire_checkbox.place(x=320*0.55/2+320, y=150, anchor="center")
|
||||
|
||||
self.ruby_sapphire_checkbox = ttk.Checkbutton(self.root, text='Emerald',variable=self.var, onvalue=0, offvalue=1, command=self.rs_selected)
|
||||
self.ruby_sapphire_checkbox.place(x=320*1.45/2+320, y=150, anchor="center")
|
||||
# Create Dropdown menu
|
||||
self.drop1 = AutocompleteCombobox(root, completevalues=self.trendy_1)
|
||||
self.drop1.place(x=320*0.55/2+320, y=360, anchor="center")
|
||||
self.drop1.config(width = 17)
|
||||
|
||||
self.drop2 = AutocompleteCombobox(root, completevalues=self.trendy_2)
|
||||
self.drop2.place(x=320*1.45/2+320, y=360, anchor="center")
|
||||
self.drop2.config(width = 17)
|
||||
|
||||
vcmd = (self.root.register(self.validateNumber), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
|
||||
|
||||
tid_label = ttk.Label(root, text='Trainer ID')
|
||||
tid_label.place(x=320*1.5/7+320, y=200, anchor="w")
|
||||
|
||||
sv = StringVar()
|
||||
sv.trace("w", lambda name, index, mode, sv=sv: self.maxNumberCallback(sv, 0xFFFF, 0))
|
||||
self.tid_entry = ttk.Entry(root, validate="key", validatecommand=vcmd, textvariable=sv, width=10)
|
||||
self.tid_entry.place(x=320*3.5/7+320, y=200, anchor="w")
|
||||
|
||||
lot_label = ttk.Label(root, text='Lottery No.')
|
||||
lot_label.place(x=320*1.5/7+320, y=225, anchor="w")
|
||||
|
||||
sv = StringVar()
|
||||
sv.trace("w", lambda name, index, mode, sv=sv: self.maxNumberCallback(sv, 0xFFFF, 1))
|
||||
self.lot_enrty = ttk.Entry(root, validate="key", validatecommand=vcmd, textvariable=sv, width=10)
|
||||
self.lot_enrty.place(x=320*3.5/7+320, y=225, anchor="w")
|
||||
def goToFeebasSpot(self, spot_id):
|
||||
"""
|
||||
This function changes the position of the movable map to the desired Feebas Spot. The map is 640px wide and 2240px long.
|
||||
The edges of the map on the canvas has the following coordinates:
|
||||
- x(0) = 480
|
||||
- x(640) = -160
|
||||
- y(0) = 1400
|
||||
- y(2240) = -840
|
||||
|
||||
sid_label = ttk.Label(root, text='Secret ID')
|
||||
sid_label.place(x=320*1.5/7+320, y=250, anchor="w")
|
||||
|
||||
self.sid_entry = ttk.Label(root, text='')
|
||||
self.sid_entry.place(x=320*3.5/7+320, y=250, anchor="w")
|
||||
|
||||
calc_button = ttk.Button(root, text='Calculate', command=self.calculateFeebasSpots, state= NORMAL)
|
||||
calc_button.place(x=320*2/7+320, y=430, anchor="center")
|
||||
clear_button = ttk.Button(root, text='Clear', command=self.clearFeebasSpots, state= NORMAL)
|
||||
clear_button.place(x=320*5/7+320, y=430, anchor="center")
|
||||
|
||||
self.feebas_spot_buttons = []
|
||||
|
||||
spot_button = ttk.Button(root, text='1', command= lambda: self.goToFeebasSpot(0), state= DISABLED, width=4)
|
||||
spot_button.place(x=320/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='2', command= lambda: self.goToFeebasSpot(1), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*2/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='3', command= lambda: self.goToFeebasSpot(2), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*3/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='4', command= lambda: self.goToFeebasSpot(3), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*4/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='5', command= lambda: self.goToFeebasSpot(4), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*5/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
|
||||
spot_button = ttk.Button(root, text='6', command= lambda: self.goToFeebasSpot(5), state= DISABLED, width=4)
|
||||
spot_button.place(x=320*6/7+320, y=500, anchor="center")
|
||||
self.feebas_spot_buttons.append(spot_button)
|
||||
Args:
|
||||
self: The class itself
|
||||
spot_id: The Feebas Spot ID ranging from 0 - 5
|
||||
"""
|
||||
calculated_spots = self.feebas_calcs.getFeebasSpotCoordinates()
|
||||
|
||||
# Calculate the new position of the map
|
||||
self.current_image_xpos = (640 - calculated_spots[spot_id][0] - 160)
|
||||
self.current_image_ypos = (2240 - calculated_spots[spot_id][1] - 840)
|
||||
|
||||
# Check if the image doesn't go past any of these set boundaries
|
||||
if(self.current_image_xpos > 16*20):
|
||||
self.current_image_xpos = 16*20
|
||||
elif(self.current_image_xpos < 0):
|
||||
self.current_image_xpos = 0
|
||||
if(self.current_image_ypos > 16*70):
|
||||
self.current_image_ypos = 16*70
|
||||
elif(self.current_image_ypos < -16*12):
|
||||
self.current_image_ypos = -16*12
|
||||
|
||||
def goToFeebasSpot(self, spot_id):
|
||||
calculated_spots = self.feebas_calcs.getFeebasSpotCoordinates()
|
||||
# x(0) = 480
|
||||
# x(640) = -160
|
||||
# y{0) = 1400
|
||||
# y(2240) = -840
|
||||
|
||||
self.current_image_xpos = (640 - calculated_spots[spot_id][0] - 160)
|
||||
self.current_image_ypos = (2240 - calculated_spots[spot_id][1] - 840)
|
||||
if(self.current_image_xpos > 16*20):
|
||||
self.current_image_xpos = 16*20
|
||||
elif(self.current_image_xpos < 0):
|
||||
self.current_image_xpos = 0
|
||||
if(self.current_image_ypos > 16*60):
|
||||
self.current_image_ypos = 16*60
|
||||
elif(self.current_image_ypos < -16*12):
|
||||
self.current_image_ypos = -16*12
|
||||
# Draw the map on its new coordinates
|
||||
self.map_canvas.create_image(self.current_image_xpos, self.current_image_ypos, image=self.map_render)
|
||||
|
||||
img = self.canvas.create_image(self.current_image_xpos, self.current_image_ypos, image=self.render)
|
||||
def calculateFeebasSpots(self):
|
||||
"""
|
||||
This function is called when the user clicks on the "Calculate" button. This function will try to
|
||||
calculate the correct Feebas Spots and draw them on the map if possible.
|
||||
|
||||
def calculateFeebasSpots(self):
|
||||
self.feebas_calcs = FeebasCalculator(self.tid_entry.get(), self.lot_enrty.get(), self.drop1.get(), self.drop2.get(), self.var.get())
|
||||
|
||||
if(self.feebas_calcs.isFeebasFound() == False):
|
||||
self.root.bell()
|
||||
return
|
||||
|
||||
image = Image.open("./Recources/Hoenn_Route_119_E.png").convert('RGBA')
|
||||
watermark = Image.open("./Recources/Feebas_Spot_Indicator.png").convert('RGBA')
|
||||
layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
|
||||
#print(self.feebas_calcs.getSecretId())
|
||||
#self.sid_entry.config(text=str(self.feebas_calcs.getSecretId()))
|
||||
calculated_spots = self.feebas_calcs.getFeebasSpotCoordinates()
|
||||
for xy in calculated_spots:
|
||||
layer.paste(watermark, (xy[0], xy[1]))
|
||||
xy = xy[:2]
|
||||
layer2 = layer.copy()
|
||||
layer2.putalpha(180)
|
||||
layer.paste(layer2, layer)
|
||||
result = Image.alpha_composite(image, layer)
|
||||
#result.save("NewImage.png")
|
||||
self.render = ImageTk.PhotoImage(result)
|
||||
img = self.canvas.create_image(self.current_image_xpos, self.current_image_ypos, image=self.render)
|
||||
|
||||
for spot in self.feebas_spot_buttons:
|
||||
spot['state'] = "normal"
|
||||
Args:
|
||||
self: The class itself
|
||||
"""
|
||||
# GIve the parameters to the FeebasCalculator and check if it could find a feebas. If not, then make a noise to let the user know about this.
|
||||
self.feebas_calcs = FeebasCalculator(self.tid_entry.get(), self.lot_enrty.get(), self.drop1.get(), self.drop2.get(), self.is_emerald.get())
|
||||
|
||||
if(self.feebas_calcs.isFeebasFound() == False):
|
||||
self.root.bell()
|
||||
return
|
||||
|
||||
# Make a hacky string for the Secret IDs in case we got multiple results
|
||||
secret_id_string = ""
|
||||
for secret_id in self.feebas_calcs.getSecretIds():
|
||||
if(secret_id_string != ""):
|
||||
secret_id_string += ' / '
|
||||
secret_id_string += str(secret_id)
|
||||
|
||||
self.secret_id_entry.config(text=str(secret_id_string))
|
||||
|
||||
# Prepare the map and spot indicator
|
||||
map_image = Image.open(ROUTE119_PATH).convert('RGBA')
|
||||
indicator_image = Image.open(FEEBAS_SPOT_INDICATOR).convert('RGBA')
|
||||
map_layer = Image.new('RGBA', map_image.size, (0, 0, 0, 0))
|
||||
|
||||
def clearFeebasSpots(self):
|
||||
image = Image.open('./Recources/Hoenn_Route_119_E.png')
|
||||
self.render = ImageTk.PhotoImage(image)
|
||||
img = self.canvas.create_image(self.current_image_xpos, self.current_image_ypos, image=self.render)
|
||||
|
||||
for spot in self.feebas_spot_buttons:
|
||||
spot['state'] = "disabled"
|
||||
|
||||
def mousePressCanvas(self, e):
|
||||
self.current_mouse_xpos = e.x
|
||||
self.current_mouse_ypos = e.y
|
||||
|
||||
def mouseMove(self, e):
|
||||
x_diff = self.current_mouse_xpos - e.x
|
||||
y_diff = self.current_mouse_ypos - e.y
|
||||
self.current_image_xpos -= x_diff
|
||||
self.current_image_ypos -= y_diff
|
||||
if(self.current_image_xpos > 16*20):
|
||||
self.current_image_xpos = 16*20
|
||||
elif(self.current_image_xpos < 0):
|
||||
self.current_image_xpos = 0
|
||||
if(self.current_image_ypos > 16*70):
|
||||
self.current_image_ypos = 16*70
|
||||
elif(self.current_image_ypos < -16*12):
|
||||
self.current_image_ypos = -16*12
|
||||
self.current_mouse_xpos = e.x
|
||||
self.current_mouse_ypos = e.y
|
||||
|
||||
img = self.canvas.create_image(self.current_image_xpos, self.current_image_ypos, image=self.render)
|
||||
|
||||
def maxNumberCallback(self, sv, max_number, id):
|
||||
current_number = 0
|
||||
try:
|
||||
current_number = int(sv.get())
|
||||
except ValueError:
|
||||
print("Nothing")
|
||||
# Get the calculated spots and place the indicator in the map
|
||||
calculated_spots = self.feebas_calcs.getFeebasSpotCoordinates()
|
||||
for xy in calculated_spots:
|
||||
map_layer.paste(indicator_image, (xy[0], xy[1]))
|
||||
xy = xy[:2]
|
||||
indicator_layer = map_layer.copy()
|
||||
indicator_layer.putalpha(180)
|
||||
map_layer.paste(indicator_layer, map_layer)
|
||||
result = Image.alpha_composite(map_image, map_layer)
|
||||
|
||||
if current_number > max_number:
|
||||
if(id == 0):
|
||||
self.tid_entry.delete(0, END)
|
||||
self.tid_entry.insert(0, "65535")
|
||||
else:
|
||||
self.lot_enrty.delete(0, END)
|
||||
self.lot_enrty.insert(0, "65535")
|
||||
current_number = max_number
|
||||
self.root.bell()
|
||||
|
||||
def rs_selected(self):
|
||||
print("SELECTED")
|
||||
|
||||
def validateNumber(self, d, i, P, s, S, v, V, W):
|
||||
# %d = Type of action (1=insert, 0=delete, -1 for others)
|
||||
# %i = index of char string to be inserted/deleted, or -1
|
||||
# %P = value of the entry if the edit is allowed
|
||||
# %s = value of entry prior to editing
|
||||
# %S = the text string being inserted or deleted, if any
|
||||
# %v = the type of validation that is currently set
|
||||
# %V = the type of validation that triggered the callback
|
||||
# (key, focusin, focusout, forced)
|
||||
# %W = the tk name of the widget
|
||||
# place the image with the indicators back in the tool for the user to see
|
||||
self.map_render = ImageTk.PhotoImage(result)
|
||||
self.map_canvas.create_image(self.current_image_xpos, self.current_image_ypos, image=self.map_render)
|
||||
|
||||
# Activate the Feebas spot buttons to directly see where the spots are
|
||||
for spot in self.feebas_spot_buttons:
|
||||
spot['state'] = "normal"
|
||||
|
||||
# Disallow anything that isn't a number
|
||||
if S.isnumeric():
|
||||
return True
|
||||
else:
|
||||
self.root.bell()
|
||||
return False
|
||||
|
||||
|
||||
|
||||
root = Tk()
|
||||
def clearFeebasSpots(self):
|
||||
"""
|
||||
This function is called when the user clicks on the "Clear" button. This function will reset the map and get rid of any Feebas Indicators placed.
|
||||
The buttons for the Feebas spots will also be disabled.
|
||||
|
||||
root.wm_title("Finding Feebas")
|
||||
root.geometry("640x560")
|
||||
root.resizable(0,0)
|
||||
Args:
|
||||
self: The class itself
|
||||
"""
|
||||
self.secret_id_entry.config(text="")
|
||||
image = Image.open(ROUTE119_PATH)
|
||||
self.map_render = ImageTk.PhotoImage(image)
|
||||
self.map_canvas.create_image(self.current_image_xpos, self.current_image_ypos, image=self.map_render)
|
||||
|
||||
for spot in self.feebas_spot_buttons:
|
||||
spot['state'] = "disabled"
|
||||
|
||||
def mousePressCanvas(self, e):
|
||||
"""
|
||||
This function is called when the user does a leftbutton mouse press on the Route119 map. The current position of the mouse is stored in variables of this class.
|
||||
|
||||
app = Route119(root)
|
||||
Args:
|
||||
self: The class itself
|
||||
e: Mouse events
|
||||
"""
|
||||
self.current_mouse_xpos = e.x
|
||||
self.current_mouse_ypos = e.y
|
||||
|
||||
def mouseMove(self, e):
|
||||
"""
|
||||
This function is called when the user drags the canvas while having the leftbutton of the mouse pressed. The position of the map is updated based on which direction
|
||||
the user drags the mouse. Some limits have been set in place to make sure the dragging stops at the edges of the map and stays in the relevant areas.
|
||||
|
||||
root.mainloop()
|
||||
Args:
|
||||
self: The class itself
|
||||
e: Mouse events
|
||||
"""
|
||||
x_diff = self.current_mouse_xpos - e.x
|
||||
y_diff = self.current_mouse_ypos - e.y
|
||||
self.current_image_xpos -= x_diff
|
||||
self.current_image_ypos -= y_diff
|
||||
if(self.current_image_xpos > 16*20):
|
||||
self.current_image_xpos = 16*20
|
||||
elif(self.current_image_xpos < 0):
|
||||
self.current_image_xpos = 0
|
||||
if(self.current_image_ypos > 16*70):
|
||||
self.current_image_ypos = 16*70
|
||||
elif(self.current_image_ypos < -16*12):
|
||||
self.current_image_ypos = -16*12
|
||||
self.current_mouse_xpos = e.x
|
||||
self.current_mouse_ypos = e.y
|
||||
|
||||
self.map_canvas.create_image(self.current_image_xpos, self.current_image_ypos, image=self.map_render)
|
||||
|
||||
def maxNumberCallback(self, sv, max_number, id):
|
||||
"""
|
||||
This function is called whenever the user gives an input for the lottery number or the trainer ID. It will check if the value inserted is within the bounds set for it.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
sv: Holds the input made by the user
|
||||
max_number: Hold the max number set for the input field
|
||||
id: Indicates which entry field is used. 0 for Trainer ID and 1 for Lottery Number
|
||||
"""
|
||||
current_number = 0
|
||||
try:
|
||||
current_number = int(sv.get())
|
||||
except ValueError:
|
||||
print("Nothing")
|
||||
|
||||
if current_number > max_number:
|
||||
if(id == 0):
|
||||
self.tid_entry.delete(0, END)
|
||||
self.tid_entry.insert(0, "65535")
|
||||
else:
|
||||
self.lot_enrty.delete(0, END)
|
||||
self.lot_enrty.insert(0, "65535")
|
||||
current_number = max_number
|
||||
self.root.bell()
|
||||
|
||||
def validateNumber(self, d, i, P, s, S, v, V, W):
|
||||
"""
|
||||
This function is called whenever the user gives an input for the lottery number or the trainer ID. It will check if the value inserted is a number.
|
||||
It will dissalow any other characters.
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
d: Type of action (1=insert, 0=delete, -1 for others)
|
||||
i: Index of char string to be inserted/deleted, or -1
|
||||
P: Value of the entry if the edit is allowed
|
||||
s: Value of entry prior to editing
|
||||
S: The text string being inserted or deleted, if any
|
||||
v: The type of validation that is currently set
|
||||
V: The type of validation that triggered the callback
|
||||
(key, focusin, focusout, forced)
|
||||
W: The tk name of the widget
|
||||
"""
|
||||
|
||||
# Disallow anything that isn't a number
|
||||
if S.isnumeric():
|
||||
return True
|
||||
else:
|
||||
self.root.bell()
|
||||
return False
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = Tk()
|
||||
|
||||
root.wm_title("Finding Feebas")
|
||||
root.geometry("640x560")
|
||||
root.resizable(0,0)
|
||||
root.iconbitmap(default='Resources/Icon/LogoGoppier.ico')
|
||||
|
||||
app = Route119(root)
|
||||
|
||||
root.mainloop()
|
||||
515
trendyPhrase.py
@@ -1,216 +1,321 @@
|
||||
"""
|
||||
trendyPhrase.py
|
||||
|
||||
This file contains all the possible words used in the Trendy Phrase and also has a class that contains all the parameters of the Dewford Trend.
|
||||
"""
|
||||
|
||||
class DewfordTrend:
|
||||
def __init__(self):
|
||||
self.trendiness = 0
|
||||
self.max_trendiness = 0
|
||||
self.is_gaining_trendiness = False
|
||||
self.random_value = 0
|
||||
self.easy_chat_words = ["", ""]
|
||||
|
||||
def setTrendiness(self, value):
|
||||
self.trendiness = value
|
||||
|
||||
def getTrendiness(self):
|
||||
return self.trendiness
|
||||
|
||||
def setMaxTrendiness(self, value):
|
||||
self.max_trendiness = value
|
||||
|
||||
def getMaxTrendiness(self):
|
||||
return self.max_trendiness
|
||||
|
||||
def setIsGainingTrendiness(self, value):
|
||||
self.is_gaining_trendiness = value
|
||||
|
||||
def getIsGainingTrendiness(self):
|
||||
return self.is_gaining_trendiness
|
||||
|
||||
def setRandomValue(self, value):
|
||||
self.random_value = value
|
||||
|
||||
def getRandomValue(self):
|
||||
return self.random_value
|
||||
|
||||
def setPhrase(self, phrase_1, phrase_2):
|
||||
self.easy_chat_words[0] = phrase_1
|
||||
self.easy_chat_words[1] = phrase_2
|
||||
|
||||
def getPhrase(self):
|
||||
return self.easy_chat_words
|
||||
"""
|
||||
This class holds the parameters of each Trendy Phrase used in Dewford
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
This function initialises the Trendy Phrase parameters
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
"""
|
||||
self.trendiness = 0
|
||||
self.max_trendiness = 0
|
||||
self.is_gaining_trendiness = False
|
||||
self.random_value = 0
|
||||
self.easy_chat_words = ["", ""]
|
||||
|
||||
def setTrendiness(self, trendiness):
|
||||
"""
|
||||
This function sets the trendiness value for this Trendy Phrase
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
trendiness: The value of the phrase's trendiness
|
||||
"""
|
||||
self.trendiness = trendiness
|
||||
|
||||
def getTrendiness(self):
|
||||
"""
|
||||
This function returns the trendiness value for this Trendy Phrase
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
|
||||
Returns:
|
||||
self.trendiness: The trendiness value in the form on an integer
|
||||
"""
|
||||
return self.trendiness
|
||||
|
||||
def setMaxTrendiness(self, max_trendiness):
|
||||
"""
|
||||
This function sets the maximum trendiness value for this Trendy Phrase
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
max_trendiness: The value of the phrase's maximum trendiness
|
||||
"""
|
||||
self.max_trendiness = max_trendiness
|
||||
|
||||
def getMaxTrendiness(self):
|
||||
"""
|
||||
This function returns the maximum trendiness value for this Trendy Phrase
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
|
||||
Returns:
|
||||
self.max_trendiness: The maximum trendiness value in the form on an integer
|
||||
"""
|
||||
return self.max_trendiness
|
||||
|
||||
def setIsGainingTrendiness(self, is_gaining_trendiness):
|
||||
"""
|
||||
This function sets the is_gaining_trendiness value
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
is_gaining_trendiness: A boolean value that decides if the phrase is gaining trendiness or not
|
||||
"""
|
||||
self.is_gaining_trendiness = is_gaining_trendiness
|
||||
|
||||
def getIsGainingTrendiness(self):
|
||||
"""
|
||||
This function returns the is_gaining_trendiness for this Trendy Phrase
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
|
||||
Returns:
|
||||
self.is_gaining_trendiness: A boolean value that decides if the phrase is gaining trendiness or not
|
||||
"""
|
||||
return self.is_gaining_trendiness
|
||||
|
||||
def setRandomValue(self, random_value):
|
||||
"""
|
||||
This function sets the random value for this Trendy Phrase
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
random_value: The random value of this Trendy Phrase
|
||||
"""
|
||||
self.random_value = random_value
|
||||
|
||||
def getRandomValue(self):
|
||||
"""
|
||||
This function returns the random value for this Trendy Phrase
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
|
||||
Returns:
|
||||
self.random_value: The random value in the form on an integer
|
||||
"""
|
||||
return self.random_value
|
||||
|
||||
def setPhrase(self, easy_chat_word_1, easy_chat_word_2):
|
||||
"""
|
||||
This function sets the Trendy Phrase using two Easy Chat words
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
easy_chat_word_1: The first word of the Trendy Phrase
|
||||
easy_chat_word_2: The second word of the Trendy Phrase
|
||||
"""
|
||||
self.easy_chat_words[0] = easy_chat_word_1
|
||||
self.easy_chat_words[1] = easy_chat_word_2
|
||||
|
||||
def getPhrase(self):
|
||||
"""
|
||||
This function returns the Easy Chat words for this Trendy Phrase
|
||||
|
||||
Args:
|
||||
self: The class itself
|
||||
|
||||
Returns:
|
||||
self.easy_chat_words: The Easy Chat words for this Trendy Phrase
|
||||
"""
|
||||
return self.easy_chat_words
|
||||
|
||||
|
||||
"""
|
||||
This list holds all the Easy Chat words for the category "Conditions"
|
||||
"""
|
||||
group_conditions=[
|
||||
"HOT",
|
||||
"EXISTS",
|
||||
"EXCESS",
|
||||
"APPROVED",
|
||||
"HAS",
|
||||
"GOOD",
|
||||
"LESS",
|
||||
"MOMENTUM",
|
||||
"GOING",
|
||||
"WEIRD",
|
||||
"BUSY",
|
||||
"TOGETHER",
|
||||
"FULL",
|
||||
"ABSENT",
|
||||
"BEING",
|
||||
"NEED",
|
||||
"TASTY",
|
||||
"SKILLED",
|
||||
"NOISY",
|
||||
"BIG",
|
||||
"LATE",
|
||||
"CLOSE",
|
||||
"DOCILE",
|
||||
"AMUSING",
|
||||
"ENTERTAINING",
|
||||
"PERFECTION",
|
||||
"PRETTY",
|
||||
"HEALTHY",
|
||||
"EXCELLENT",
|
||||
"UPSIDEDOWN",
|
||||
"COLD",
|
||||
"REFRESHING",
|
||||
"UNAVOIDABLE",
|
||||
"MUCH",
|
||||
"OVERWHELMING",
|
||||
"FABULOUS",
|
||||
"ELSE",
|
||||
"EXPENSIVE",
|
||||
"CORRECT",
|
||||
"IMPOSSIBLE",
|
||||
"SMALL",
|
||||
"DIFFERENT",
|
||||
"TIRED",
|
||||
"SKILL",
|
||||
"TOP",
|
||||
"NONSTOP",
|
||||
"PREPOSTEROUS",
|
||||
"NONE",
|
||||
"NOTHING",
|
||||
"NATURAL",
|
||||
"BECOMES",
|
||||
"LUKEWARM",
|
||||
"FAST",
|
||||
"LOW",
|
||||
"AWFUL",
|
||||
"ALONE",
|
||||
"BORED",
|
||||
"SECRET",
|
||||
"MYSTERY",
|
||||
"LACKS",
|
||||
"BEST",
|
||||
"LOUSY",
|
||||
"MISTAKE",
|
||||
"KIND",
|
||||
"WELL",
|
||||
"WEAKENED",
|
||||
"SIMPLE",
|
||||
"SEEMS",
|
||||
"BADLY"
|
||||
"HOT",
|
||||
"EXISTS",
|
||||
"EXCESS",
|
||||
"APPROVED",
|
||||
"HAS",
|
||||
"GOOD",
|
||||
"LESS",
|
||||
"MOMENTUM",
|
||||
"GOING",
|
||||
"WEIRD",
|
||||
"BUSY",
|
||||
"TOGETHER",
|
||||
"FULL",
|
||||
"ABSENT",
|
||||
"BEING",
|
||||
"NEED",
|
||||
"TASTY",
|
||||
"SKILLED",
|
||||
"NOISY",
|
||||
"BIG",
|
||||
"LATE",
|
||||
"CLOSE",
|
||||
"DOCILE",
|
||||
"AMUSING",
|
||||
"ENTERTAINING",
|
||||
"PERFECTION",
|
||||
"PRETTY",
|
||||
"HEALTHY",
|
||||
"EXCELLENT",
|
||||
"UPSIDEDOWN",
|
||||
"COLD",
|
||||
"REFRESHING",
|
||||
"UNAVOIDABLE",
|
||||
"MUCH",
|
||||
"OVERWHELMING",
|
||||
"FABULOUS",
|
||||
"ELSE",
|
||||
"EXPENSIVE",
|
||||
"CORRECT",
|
||||
"IMPOSSIBLE",
|
||||
"SMALL",
|
||||
"DIFFERENT",
|
||||
"TIRED",
|
||||
"SKILL",
|
||||
"TOP",
|
||||
"NONSTOP",
|
||||
"PREPOSTEROUS",
|
||||
"NONE",
|
||||
"NOTHING",
|
||||
"NATURAL",
|
||||
"BECOMES",
|
||||
"LUKEWARM",
|
||||
"FAST",
|
||||
"LOW",
|
||||
"AWFUL",
|
||||
"ALONE",
|
||||
"BORED",
|
||||
"SECRET",
|
||||
"MYSTERY",
|
||||
"LACKS",
|
||||
"BEST",
|
||||
"LOUSY",
|
||||
"MISTAKE",
|
||||
"KIND",
|
||||
"WELL",
|
||||
"WEAKENED",
|
||||
"SIMPLE",
|
||||
"SEEMS",
|
||||
"BADLY"
|
||||
]
|
||||
|
||||
"""
|
||||
This list holds all the Easy Chat words for the category "Lifestyles"
|
||||
"""
|
||||
group_lifestyles=[
|
||||
"CHORES",
|
||||
"HOME",
|
||||
"MONEY",
|
||||
"ALLOWANCE",
|
||||
"BATH",
|
||||
"CONVERSATION",
|
||||
"SCHOOL",
|
||||
"COMMEMORATE",
|
||||
"HABIT",
|
||||
"GROUP",
|
||||
"WORD",
|
||||
"STORE",
|
||||
"SERVICE",
|
||||
"WORK",
|
||||
"SYSTEM",
|
||||
"TRAIN",
|
||||
"CLASS",
|
||||
"LESSONS",
|
||||
"INFORMATION",
|
||||
"LIVING",
|
||||
"TEACHER",
|
||||
"TOURNAMENT",
|
||||
"LETTER",
|
||||
"EVENT",
|
||||
"DIGITAL",
|
||||
"TEST",
|
||||
"DEPT_STORE",
|
||||
"TELEVISION",
|
||||
"PHONE",
|
||||
"ITEM",
|
||||
"NAME",
|
||||
"NEWS",
|
||||
"POPULAR",
|
||||
"PARTY",
|
||||
"STUDY",
|
||||
"MACHINE",
|
||||
"MAIL",
|
||||
"MESSAGE",
|
||||
"PROMISE",
|
||||
"DREAM",
|
||||
"KINDERGARTEN",
|
||||
"LIFE",
|
||||
"RADIO",
|
||||
"RENTAL",
|
||||
"WORLD"
|
||||
"CHORES",
|
||||
"HOME",
|
||||
"MONEY",
|
||||
"ALLOWANCE",
|
||||
"BATH",
|
||||
"CONVERSATION",
|
||||
"SCHOOL",
|
||||
"COMMEMORATE",
|
||||
"HABIT",
|
||||
"GROUP",
|
||||
"WORD",
|
||||
"STORE",
|
||||
"SERVICE",
|
||||
"WORK",
|
||||
"SYSTEM",
|
||||
"TRAIN",
|
||||
"CLASS",
|
||||
"LESSONS",
|
||||
"INFORMATION",
|
||||
"LIVING",
|
||||
"TEACHER",
|
||||
"TOURNAMENT",
|
||||
"LETTER",
|
||||
"EVENT",
|
||||
"DIGITAL",
|
||||
"TEST",
|
||||
"DEPT_STORE",
|
||||
"TELEVISION",
|
||||
"PHONE",
|
||||
"ITEM",
|
||||
"NAME",
|
||||
"NEWS",
|
||||
"POPULAR",
|
||||
"PARTY",
|
||||
"STUDY",
|
||||
"MACHINE",
|
||||
"MAIL",
|
||||
"MESSAGE",
|
||||
"PROMISE",
|
||||
"DREAM",
|
||||
"KINDERGARTEN",
|
||||
"LIFE",
|
||||
"RADIO",
|
||||
"RENTAL",
|
||||
"WORLD"
|
||||
]
|
||||
|
||||
"""
|
||||
This list holds all the Easy Chat words for the category "Hobbies"
|
||||
"""
|
||||
group_hobbies=[
|
||||
"IDOL",
|
||||
"ANIME",
|
||||
"SONG",
|
||||
"MOVIE",
|
||||
"SWEETS",
|
||||
"CHAT",
|
||||
"CHILD_S_PLAY",
|
||||
"TOYS",
|
||||
"MUSIC",
|
||||
"CARDS",
|
||||
"SHOPPING",
|
||||
"CAMERA",
|
||||
"VIEWING",
|
||||
"SPECTATOR",
|
||||
"GOURMET",
|
||||
"GAME",
|
||||
"RPG",
|
||||
"COLLECTION",
|
||||
"COMPLETE",
|
||||
"MAGAZINE",
|
||||
"WALK",
|
||||
"BIKE",
|
||||
"HOBBY",
|
||||
"SPORTS",
|
||||
"SOFTWARE",
|
||||
"SONGS",
|
||||
"DIET",
|
||||
"TREASURE",
|
||||
"TRAVEL",
|
||||
"DANCE",
|
||||
"CHANNEL",
|
||||
"MAKING",
|
||||
"FISHING",
|
||||
"DATE",
|
||||
"DESIGN",
|
||||
"LOCOMOTIVE",
|
||||
"PLUSH_DOLL",
|
||||
"PC",
|
||||
"FLOWERS",
|
||||
"HERO",
|
||||
"NAP",
|
||||
"HEROINE",
|
||||
"FASHION",
|
||||
"ADVENTURE",
|
||||
"BOARD",
|
||||
"BALL",
|
||||
"BOOK",
|
||||
"FESTIVAL",
|
||||
"COMICS",
|
||||
"HOLIDAY",
|
||||
"PLANS",
|
||||
"TRENDY",
|
||||
"VACATION",
|
||||
"LOOK"
|
||||
"IDOL",
|
||||
"ANIME",
|
||||
"SONG",
|
||||
"MOVIE",
|
||||
"SWEETS",
|
||||
"CHAT",
|
||||
"CHILD_S_PLAY",
|
||||
"TOYS",
|
||||
"MUSIC",
|
||||
"CARDS",
|
||||
"SHOPPING",
|
||||
"CAMERA",
|
||||
"VIEWING",
|
||||
"SPECTATOR",
|
||||
"GOURMET",
|
||||
"GAME",
|
||||
"RPG",
|
||||
"COLLECTION",
|
||||
"COMPLETE",
|
||||
"MAGAZINE",
|
||||
"WALK",
|
||||
"BIKE",
|
||||
"HOBBY",
|
||||
"SPORTS",
|
||||
"SOFTWARE",
|
||||
"SONGS",
|
||||
"DIET",
|
||||
"TREASURE",
|
||||
"TRAVEL",
|
||||
"DANCE",
|
||||
"CHANNEL",
|
||||
"MAKING",
|
||||
"FISHING",
|
||||
"DATE",
|
||||
"DESIGN",
|
||||
"LOCOMOTIVE",
|
||||
"PLUSH_DOLL",
|
||||
"PC",
|
||||
"FLOWERS",
|
||||
"HERO",
|
||||
"NAP",
|
||||
"HEROINE",
|
||||
"FASHION",
|
||||
"ADVENTURE",
|
||||
"BOARD",
|
||||
"BALL",
|
||||
"BOOK",
|
||||
"FESTIVAL",
|
||||
"COMICS",
|
||||
"HOLIDAY",
|
||||
"PLANS",
|
||||
"TRENDY",
|
||||
"VACATION",
|
||||
"LOOK"
|
||||
]
|
||||