Paginate garden
parent
2fcdb01577
commit
8f99063b5b
|
@ -48,11 +48,13 @@ If your plant goes 5 days without water, it will die!
|
|||
* ASCII art only shows first stage of growth - more coming soon!
|
||||
|
||||
### to-dos
|
||||
* Add day/night ASCII art
|
||||
* Finish garden display ('garden' function)
|
||||
* Finish garden feature
|
||||
* Switch to database instead of .dat file
|
||||
* Allows you to water neighbor's plants
|
||||
* Plant end of life (seeding/pollination)
|
||||
* Harvest plant at end of life (gather seeds)
|
||||
* Create harvest file with a log of all previous plants
|
||||
* Plant pollination - cross-breed with neighbor plants to unlock second-gen plants
|
||||
* Share seeds with other users
|
||||
* Global events
|
||||
* Server API to have rain storms, heat waves, insects
|
||||
* Name your plant
|
||||
|
|
44
botany.py
44
botany.py
|
@ -224,7 +224,7 @@ class Plant(object):
|
|||
# Create plant mutation
|
||||
# TODO: when out of debug this needs to be set to high number
|
||||
# Increase this # to make mutation rarer (chance 1 out of x each second)
|
||||
CONST_MUTATION_RARITY = 3000
|
||||
CONST_MUTATION_RARITY = 5000
|
||||
mutation_seed = random.randint(1,CONST_MUTATION_RARITY)
|
||||
if mutation_seed == CONST_MUTATION_RARITY:
|
||||
# mutation gained!
|
||||
|
@ -281,7 +281,6 @@ class Plant(object):
|
|||
def life(self):
|
||||
# I've created life :)
|
||||
while True:
|
||||
time.sleep(1)
|
||||
if not self.dead:
|
||||
if self.watered_24h:
|
||||
self.ticks += 1
|
||||
|
@ -297,8 +296,11 @@ class Plant(object):
|
|||
# Do something else
|
||||
pass
|
||||
# TODO: event check
|
||||
time.sleep(1)
|
||||
|
||||
class DataManager(object):
|
||||
# TODO: garden file stuff has a race condition - need to find and
|
||||
# eliminate it.
|
||||
# handles user data, puts a .botany dir in user's home dir (OSX/Linux)
|
||||
user_dir = os.path.expanduser("~")
|
||||
botany_dir = os.path.join(user_dir,'.botany')
|
||||
|
@ -309,6 +311,8 @@ class DataManager(object):
|
|||
savefile_path = os.path.join(botany_dir, savefile_name)
|
||||
garden_file_path = os.path.join(game_dir, 'garden_file.dat')
|
||||
garden_json_path = os.path.join(game_dir, 'garden_file.json')
|
||||
harvest_file_path = os.path.join(botany_dir, 'harvest_file.dat')
|
||||
harvest_json_path = os.path.join(botany_dir, 'harvest_file.json')
|
||||
|
||||
def __init__(self):
|
||||
self.this_user = getpass.getuser()
|
||||
|
@ -346,17 +350,16 @@ class DataManager(object):
|
|||
self.save_plant(this_plant)
|
||||
self.data_write_json(this_plant)
|
||||
self.garden_update(this_plant)
|
||||
self.harvest_plant(this_plant)
|
||||
this_plant.unlock_new_creation()
|
||||
time.sleep(.1)
|
||||
|
||||
def autosave(self, this_plant):
|
||||
# running on thread
|
||||
# running on thread, saves plant every 5s
|
||||
while True:
|
||||
self.save_plant(this_plant)
|
||||
self.data_write_json(this_plant)
|
||||
self.garden_update(this_plant)
|
||||
# TODO: change after debug
|
||||
#time.sleep(60)
|
||||
time.sleep(5)
|
||||
|
||||
def load_plant(self):
|
||||
|
@ -377,7 +380,6 @@ class DataManager(object):
|
|||
else:
|
||||
ticks_to_add = 0
|
||||
this_plant.ticks += ticks_to_add
|
||||
|
||||
return this_plant
|
||||
|
||||
def plant_age_convert(self,this_plant):
|
||||
|
@ -462,6 +464,35 @@ class DataManager(object):
|
|||
with open(json_file, 'w') as outfile:
|
||||
json.dump(plant_info, outfile)
|
||||
|
||||
def harvest_plant(self, this_plant):
|
||||
# harvest is a dict of dicts
|
||||
# harvest contains one entry for each plant id
|
||||
age_formatted = self.plant_age_convert(this_plant)
|
||||
this_plant_id = this_plant.plant_id
|
||||
plant_info = {
|
||||
"description":this_plant.parse_plant(),
|
||||
"age":age_formatted,
|
||||
"score":this_plant.ticks,
|
||||
}
|
||||
if os.path.isfile(self.harvest_file_path):
|
||||
# harvest file exists: load data
|
||||
with open(self.harvest_file_path, 'rb') as f:
|
||||
this_harvest = pickle.load(f)
|
||||
new_file_check = False
|
||||
else:
|
||||
this_harvest = {}
|
||||
new_file_check = True
|
||||
this_harvest[this_plant_id] = plant_info
|
||||
|
||||
# dump harvest file
|
||||
with open(self.harvest_file_path, 'wb') as f:
|
||||
pickle.dump(this_harvest, f, protocol=2)
|
||||
# dump json file
|
||||
with open(self.harvest_json_path, 'w') as outfile:
|
||||
json.dump(this_harvest, outfile)
|
||||
|
||||
return new_file_check
|
||||
|
||||
if __name__ == '__main__':
|
||||
my_data = DataManager()
|
||||
# if plant save file exists
|
||||
|
@ -474,6 +505,7 @@ if __name__ == '__main__':
|
|||
my_plant.start_life()
|
||||
my_data.start_threads(my_plant)
|
||||
botany_menu = CursedMenu(my_plant,my_data.garden_file_path)
|
||||
|
||||
my_data.save_plant(my_plant)
|
||||
my_data.data_write_json(my_plant)
|
||||
my_data.garden_update(my_plant)
|
||||
|
|
|
@ -45,16 +45,15 @@ class CursedMenu(object):
|
|||
def update_options(self):
|
||||
# Makes sure you can get a new plant if it dies
|
||||
if self.plant.dead:
|
||||
if "start over" not in self.options:
|
||||
self.options.insert(-1,"start over")
|
||||
if "harvest" not in self.options:
|
||||
self.options.insert(-1,"harvest")
|
||||
else:
|
||||
# TODO: remove after debug or bury in settings
|
||||
if self.plant.stage == 5:
|
||||
if "start over" not in self.options:
|
||||
self.options.insert(-1,"start over")
|
||||
if "harvest" not in self.options:
|
||||
self.options.insert(-1,"harvest")
|
||||
else:
|
||||
if "start over" in self.options:
|
||||
self.options.remove("start over")
|
||||
if "harvest" in self.options:
|
||||
self.options.remove("harvest")
|
||||
|
||||
def set_options(self, options):
|
||||
# Validates that the last option is "exit"
|
||||
|
@ -228,7 +227,7 @@ class CursedMenu(object):
|
|||
return
|
||||
|
||||
def format_garden_data(self,this_garden):
|
||||
|
||||
# Returns list of lists (pages) of garden entries
|
||||
plant_table = ""
|
||||
for plant_id in this_garden:
|
||||
if this_garden[plant_id]:
|
||||
|
@ -238,7 +237,11 @@ class CursedMenu(object):
|
|||
plant_table += this_plant["age"] + " - "
|
||||
plant_table += str(this_plant["score"]) + "p - "
|
||||
plant_table += this_plant["description"] + "\n"
|
||||
return plant_table
|
||||
# build list of n entries per page
|
||||
entries_per_page = self.maxy - 16
|
||||
garden_list = plant_table.splitlines()
|
||||
paginated_list = [garden_list[i:i+entries_per_page] for i in range(0,len(garden_list),entries_per_page)]
|
||||
return paginated_list
|
||||
|
||||
def draw_garden(self):
|
||||
# draws neighborhood
|
||||
|
@ -249,22 +252,47 @@ class CursedMenu(object):
|
|||
with open(self.garden_file_path, 'rb') as f:
|
||||
this_garden = pickle.load(f)
|
||||
# format data
|
||||
plant_table_pages = []
|
||||
if self.infotoggle != 2:
|
||||
# if infotoggle isn't 2, the screen currently displays other stuff
|
||||
# we want to prep the screen for showing the garden
|
||||
# Clear text area of other text (look info, etc) first
|
||||
for y, line in enumerate(clear_block.splitlines(), 2):
|
||||
self.screen.addstr(y+12, 2, line)
|
||||
self.screen.refresh()
|
||||
plant_table_formatted = self.format_garden_data(this_garden)
|
||||
plant_table_pages = self.format_garden_data(this_garden)
|
||||
self.infotoggle = 2
|
||||
else:
|
||||
plant_table_formatted = clear_bar
|
||||
for plant in this_garden:
|
||||
if not this_garden[plant]["dead"]:
|
||||
plant_table_formatted += clear_bar
|
||||
# the screen IS currently showing the garden (1 page), make the
|
||||
# text a bunch of blanks to clear it out
|
||||
big_clear_block = clear_bar * (self.maxy - 14)
|
||||
plant_table_pages.append(big_clear_block.splitlines())
|
||||
self.infotoggle = 0
|
||||
|
||||
for y, line in enumerate(plant_table_formatted.splitlines(), 2):
|
||||
self.screen.addstr(y+12, 2, line)
|
||||
self.screen.refresh()
|
||||
# print garden information OR clear it
|
||||
for page_num, page in enumerate(plant_table_pages, 1):
|
||||
# Print page text
|
||||
for y, line in enumerate(page, 2):
|
||||
self.screen.addstr(y+12, 2, line)
|
||||
if len(plant_table_pages) > 1:
|
||||
# Multiple pages, paginate and require keypress
|
||||
page_text = " --- press any key --- (%d/%d)" % (page_num, len(plant_table_pages))
|
||||
self.screen.addstr(self.maxy-2, 2, page_text)
|
||||
self.screen.getch()
|
||||
self.screen.refresh()
|
||||
# Clear page before drawing next
|
||||
for y, line in enumerate(range(self.maxy-16), 2):
|
||||
self.screen.addstr(y+12, 2, clear_bar)
|
||||
self.infotoggle = 0
|
||||
self.screen.refresh()
|
||||
else:
|
||||
self.screen.refresh()
|
||||
# self.screen.getch()
|
||||
# for y, line in enumerate(range(self.maxy-16), 2):
|
||||
# self.screen.addstr(y+12, 2, clear_bar)
|
||||
# self.screen.refresh()
|
||||
|
||||
|
||||
|
||||
def get_plant_description(self, this_plant):
|
||||
output_text = ""
|
||||
|
@ -281,6 +309,8 @@ class CursedMenu(object):
|
|||
"You wish your seed could tell you what it needs.",
|
||||
"You can feel the spirit inside your seed.",
|
||||
"These pretzels are making you thirsty.",
|
||||
"Way to plant, Ann!",
|
||||
"'To see things in the seed, that is genius' - Lao Tzu",
|
||||
],
|
||||
1:[
|
||||
"The seedling fills you with hope.",
|
||||
|
@ -308,7 +338,7 @@ class CursedMenu(object):
|
|||
"You're proud of the dedication it took to grow your " + this_species + ".",
|
||||
"The " + this_species + " looks good.",
|
||||
"You think about how good this " + this_species + " will look.",
|
||||
"The buds of your " + this_species + " are about to bloom.",
|
||||
"The buds of your " + this_species + " might bloom soon.",
|
||||
"You play your favorite song for your " + this_species + ".",
|
||||
],
|
||||
4:[
|
||||
|
@ -386,9 +416,6 @@ class CursedMenu(object):
|
|||
# load data
|
||||
# format data
|
||||
if self.infotoggle != 1:
|
||||
# TODO: when garden grows this won't clear everything.
|
||||
# for example if there are 9 people in garden it won't clear all
|
||||
# of them
|
||||
output_string = clear_bar * (self.maxy - 15)
|
||||
for y, line in enumerate(output_string.splitlines(), 2):
|
||||
self.screen.addstr(y+12, 2, line)
|
||||
|
@ -431,7 +458,7 @@ available in the readme :)
|
|||
def handle_request(self, request):
|
||||
'''this is where you do things with the request'''
|
||||
if request == None: return
|
||||
if request == "start over":
|
||||
if request == "harvest":
|
||||
self.plant.start_over()
|
||||
if request == "water":
|
||||
self.plant.water()
|
||||
|
|
Loading…
Reference in New Issue