Implement vim-style (j/k) and curses-style (ctrl+n/p) menu controls
parent
948adec959
commit
b2d1c62323
26
botany.py
26
botany.py
|
@ -36,7 +36,7 @@ from menu_screen import *
|
||||||
# - create rarer species by diff gens
|
# - create rarer species by diff gens
|
||||||
# - if neighbor plant dies, node will be removed from list
|
# - if neighbor plant dies, node will be removed from list
|
||||||
#
|
#
|
||||||
# build ascii trees
|
# build ascii plant art
|
||||||
|
|
||||||
# Make it fun to keep growing after seed level (what is reward for continuing
|
# Make it fun to keep growing after seed level (what is reward for continuing
|
||||||
# instead of starting over?
|
# instead of starting over?
|
||||||
|
@ -89,6 +89,13 @@ class Plant(object):
|
||||||
10: 'cannabis',
|
10: 'cannabis',
|
||||||
11: 'pansy',
|
11: 'pansy',
|
||||||
12: 'iris',
|
12: 'iris',
|
||||||
|
13: 'agave',
|
||||||
|
14: 'ficus',
|
||||||
|
15: 'lichen',
|
||||||
|
16: 'sage',
|
||||||
|
17: 'snapdragon',
|
||||||
|
18: 'columbine',
|
||||||
|
19: 'brugmansia',
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation_dict = {
|
mutation_dict = {
|
||||||
|
@ -138,8 +145,8 @@ class Plant(object):
|
||||||
# Constructor
|
# Constructor
|
||||||
self.plant_id = str(uuid.uuid4())
|
self.plant_id = str(uuid.uuid4())
|
||||||
# TODO: change from debug
|
# TODO: change from debug
|
||||||
self.life_stages = (10, 20, 30, 40, 50)
|
# self.life_stages = (10, 20, 30, 40, 50)
|
||||||
# self.life_stages = (3600, (3600*24)*3, (3600*24)*10, (3600*24)*20, (3600*24)*30)
|
self.life_stages = (3600*24, (3600*24)*3, (3600*24)*10, (3600*24)*20, (3600*24)*30)
|
||||||
self.stage = 0
|
self.stage = 0
|
||||||
self.mutation = 0
|
self.mutation = 0
|
||||||
self.species = random.randint(0,len(self.species_dict)-1)
|
self.species = random.randint(0,len(self.species_dict)-1)
|
||||||
|
@ -222,7 +229,7 @@ class Plant(object):
|
||||||
# Create plant mutation
|
# Create plant mutation
|
||||||
# TODO: when out of debug this needs to be set to high number (1000
|
# TODO: when out of debug this needs to be set to high number (1000
|
||||||
# even maybe)
|
# even maybe)
|
||||||
CONST_MUTATION_RARITY = 2000 # Increase this # to make mutation rarer (chance 1 out of x)
|
CONST_MUTATION_RARITY = 3000 # Increase this # to make mutation rarer (chance 1 out of x)
|
||||||
mutation_seed = random.randint(1,CONST_MUTATION_RARITY)
|
mutation_seed = random.randint(1,CONST_MUTATION_RARITY)
|
||||||
if mutation_seed == CONST_MUTATION_RARITY:
|
if mutation_seed == CONST_MUTATION_RARITY:
|
||||||
# mutation gained!
|
# mutation gained!
|
||||||
|
@ -275,11 +282,6 @@ class Plant(object):
|
||||||
|
|
||||||
def life(self):
|
def life(self):
|
||||||
# I've created life :)
|
# I've created life :)
|
||||||
# TODO: change out of debug
|
|
||||||
# TODO: variable stages of life
|
|
||||||
# day = 3600*24
|
|
||||||
# life_stages = (1*day, 2*day, 3*day, 4*day, 5*day)
|
|
||||||
# leave this untouched bc it works for now
|
|
||||||
while True:
|
while True:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if not self.dead:
|
if not self.dead:
|
||||||
|
@ -291,14 +293,15 @@ class Plant(object):
|
||||||
if self.mutate_check():
|
if self.mutate_check():
|
||||||
1==1
|
1==1
|
||||||
if self.water_check():
|
if self.water_check():
|
||||||
|
# Do something
|
||||||
1==1
|
1==1
|
||||||
if self.dead_check():
|
if self.dead_check():
|
||||||
|
# Do something else
|
||||||
1==1
|
1==1
|
||||||
# TODO: event check
|
# TODO: event check
|
||||||
|
|
||||||
class DataManager(object):
|
class DataManager(object):
|
||||||
# handles user data, puts a .botany dir in user's home dir (OSX/Linux)
|
# handles user data, puts a .botany dir in user's home dir (OSX/Linux)
|
||||||
# TODO: windows... lol
|
|
||||||
user_dir = os.path.expanduser("~")
|
user_dir = os.path.expanduser("~")
|
||||||
botany_dir = os.path.join(user_dir,'.botany')
|
botany_dir = os.path.join(user_dir,'.botany')
|
||||||
game_dir = os.path.dirname(os.path.realpath(__file__))
|
game_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
@ -338,8 +341,7 @@ class DataManager(object):
|
||||||
autosave_thread.start()
|
autosave_thread.start()
|
||||||
|
|
||||||
def death_check_update(self,this_plant):
|
def death_check_update(self,this_plant):
|
||||||
# .1 second updates to minimize race condition
|
# .1 second updates and lock to minimize race condition
|
||||||
# TODO: improve how this is handled to eliminate race condition
|
|
||||||
while True:
|
while True:
|
||||||
is_dead = this_plant.dead_check()
|
is_dead = this_plant.dead_check()
|
||||||
if is_dead:
|
if is_dead:
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import curses, os, traceback, threading, time, datetime, pickle, operator, random
|
import curses, os, traceback, threading, time, datetime, pickle, operator, random
|
||||||
|
|
||||||
class CursedMenu(object):
|
class CursedMenu(object):
|
||||||
#TODO: create a side panel with log of events..?
|
|
||||||
#TODO: name your plant
|
#TODO: name your plant
|
||||||
'''A class which abstracts the horrors of building a curses-based menu system'''
|
'''A class which abstracts the horrors of building a curses-based menu system'''
|
||||||
def __init__(self, this_plant, this_garden_file_path):
|
def __init__(self, this_plant, this_garden_file_path):
|
||||||
|
@ -65,8 +64,6 @@ class CursedMenu(object):
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
# Draw the menu and lines
|
# Draw the menu and lines
|
||||||
# TODO: this needs to either display the default menu screen or the
|
|
||||||
# garden/leaderboard thing
|
|
||||||
# TODO: display refresh is hacky. Could be more precise
|
# TODO: display refresh is hacky. Could be more precise
|
||||||
self.screen.refresh()
|
self.screen.refresh()
|
||||||
try:
|
try:
|
||||||
|
@ -162,15 +159,21 @@ class CursedMenu(object):
|
||||||
user_in = self.screen.getch() # Gets user input
|
user_in = self.screen.getch() # Gets user input
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.__exit__()
|
self.__exit__()
|
||||||
|
# DEBUG KEYS
|
||||||
|
# self.screen.addstr(1, 1, str(user_in), curses.A_NORMAL)
|
||||||
|
# self.screen.refresh()
|
||||||
|
|
||||||
|
# Resize sends curses.KEY_RESIZE, update display
|
||||||
|
if user_in == curses.KEY_RESIZE:
|
||||||
|
self.maxy,self.maxx = self.screen.getmaxyx()
|
||||||
|
self.screen.clear()
|
||||||
|
self.screen.refresh()
|
||||||
|
|
||||||
# enter and exit Keys are special cases
|
# enter and exit Keys are special cases
|
||||||
if user_in == 10:
|
if user_in == 10:
|
||||||
return self.options[self.selected]
|
return self.options[self.selected]
|
||||||
if user_in == 27:
|
if user_in == 27:
|
||||||
return self.options[-1]
|
return self.options[-1]
|
||||||
if user_in == curses.KEY_RESIZE:
|
|
||||||
self.maxy,self.maxx = self.screen.getmaxyx()
|
|
||||||
self.screen.clear()
|
|
||||||
self.screen.refresh()
|
|
||||||
|
|
||||||
# this is a number; check to see if we can set it
|
# this is a number; check to see if we can set it
|
||||||
if user_in >= ord('1') and user_in <= ord(str(min(9,len(self.options)+1))):
|
if user_in >= ord('1') and user_in <= ord(str(min(9,len(self.options)+1))):
|
||||||
|
@ -178,9 +181,11 @@ class CursedMenu(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
# increment or Decrement
|
# increment or Decrement
|
||||||
if user_in == curses.KEY_DOWN: # down arrow
|
down_keys = [curses.KEY_DOWN, 14, 106]
|
||||||
|
up_keys = [curses.KEY_UP, 16, 107]
|
||||||
|
if user_in in down_keys: # down arrow
|
||||||
self.selected += 1
|
self.selected += 1
|
||||||
if user_in == curses.KEY_UP: # up arrow
|
if user_in in up_keys: # up arrow
|
||||||
self.selected -=1
|
self.selected -=1
|
||||||
self.selected = self.selected % len(self.options)
|
self.selected = self.selected % len(self.options)
|
||||||
return
|
return
|
||||||
|
@ -344,16 +349,17 @@ class CursedMenu(object):
|
||||||
# load data
|
# load data
|
||||||
# format data
|
# format data
|
||||||
if self.infotoggle != 1:
|
if self.infotoggle != 1:
|
||||||
# TODO: clear the bar first
|
|
||||||
# TODO: when garden grows this won't clear everything.
|
# TODO: when garden grows this won't clear everything.
|
||||||
output_string = clear_bar * 8
|
# 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):
|
for y, line in enumerate(output_string.splitlines(), 2):
|
||||||
self.screen.addstr(y+12, 2, line)
|
self.screen.addstr(y+12, 2, line)
|
||||||
self.screen.refresh()
|
self.screen.refresh()
|
||||||
output_string = self.get_plant_description(this_plant)
|
output_string = self.get_plant_description(this_plant)
|
||||||
self.infotoggle = 1
|
self.infotoggle = 1
|
||||||
else:
|
else:
|
||||||
output_string = clear_bar * 4
|
output_string = clear_bar * 3
|
||||||
self.infotoggle = 0
|
self.infotoggle = 0
|
||||||
|
|
||||||
for y, line in enumerate(output_string.splitlines(), 2):
|
for y, line in enumerate(output_string.splitlines(), 2):
|
||||||
|
|
Loading…
Reference in New Issue