Gardening.py (view raw)
1import random, os, time, datetime
2from Constants import *
3
4water_duration = 3600 * 24
5death_duration = 6 * water_duration
6stage_factors = (1, 3, 10, 20, 30)
7indicator_squares = 6
8mutation_rarity = 20000 # Increase this # to make mutation rarer (chance 1 out of x each second)
9max_plant_rarity = 256.0
10
11class Plant(object):
12 # This is your plant!
13 def __init__(self, owner, generation=1):
14 # Constructor
15 self.points = 0 # one point per second
16 self.life_stages = tuple(st * water_duration for st in stage_factors)
17 self.stage = 0
18 self.mutation = 0
19 self.species = random.randint(0, len(species_list) - 1)
20 self.color = random.randint(0, len(color_list) - 1)
21 self.name = plant_names[random.randint(0, len(plant_names) - 1)]
22 self.rarity = self.rarity_check()
23 self.generation = generation
24 self.generation_bonus = 1 + (0.2 * (generation - 1))
25 self.dead = False
26 self.owner = owner
27 self.start_time = int(time.time())
28 self.last_update = self.start_time
29 self.last_water = self.start_time - water_duration
30
31 def update(self):
32 now = int(time.time())
33 water_delta = now - self.last_water
34 if water_delta > death_duration:
35 self.dead = True
36 return
37
38 increase = min(water_delta, water_duration) - min(self.last_update - self.last_water, water_duration)
39
40 if increase != 0:
41 self.points += increase
42 self.mutate_check(increase)
43
44 stages = tuple(th / self.generation_bonus for th in self.life_stages) # bonus is applied to stage thresholds
45 count = 0
46 closest = None
47 delta = self.points
48
49 for n in stages:
50 if (n <= delta and (closest is None or (delta - n) < (delta - closest))):
51 closest = n
52 count += 1
53
54 self.stage = count
55 self.last_update = now
56
57 def parse_plant(self):
58 # Converts plant data to human-readable format
59 output = ""
60 if self.stage >= 3:
61 output += rarity_list[self.rarity] + " "
62 if self.mutation != 0:
63 output += mutation_list[self.mutation] + " "
64 if self.stage >= 4:
65 output += color_list[self.color] + " "
66 output += stage_list[self.stage] + " "
67 if self.stage >= 2:
68 output += species_list[self.species] + " "
69 return output.strip()
70
71 def rarity_check(self):
72 # Generate plant rarity
73 rare_seed = random.randint(1,max_plant_rarity)
74 common_range = round((2.0 / 3) * max_plant_rarity)
75 uncommon_range = round((2.0 / 3) * (max_plant_rarity - common_range))
76 rare_range = round((2.0 / 3) * (max_plant_rarity - common_range - uncommon_range))
77 legendary_range = round((2.0 / 3) * (max_plant_rarity - common_range - uncommon_range - rare_range))
78
79 common_max = common_range
80 uncommon_max = common_max + uncommon_range
81 rare_max = uncommon_max + rare_range
82 legendary_max = rare_max + legendary_range
83 godly_max = max_plant_rarity
84
85 if 0 <= rare_seed <= common_max:
86 return 0
87 elif common_max < rare_seed <= uncommon_max:
88 return 1
89 elif uncommon_max < rare_seed <= rare_max:
90 return 2
91 elif rare_max < rare_seed <= legendary_max:
92 return 3
93 elif legendary_max < rare_seed <= godly_max:
94 return 4
95
96 def mutate_check(self, increase):
97 # Create plant mutation
98 mutation_seed = random.randint(increase, mutation_rarity)
99 if mutation_seed == mutation_rarity:
100 # mutation gained!
101 mutation = random.randint(0, len(self.mutation_list) - 1)
102 if self.mutation == 0:
103 self.mutation = mutation
104 return True
105 else:
106 return False
107
108 def water(self):
109 if not self.dead:
110 self.last_water = int(time.time())
111
112 def start_over(self):
113 next_generation = self.generation if self.dead else self.generation + 1
114 self.__init__(self.owner, next_generation)
115
116def get_plant_water(plant: Plant):
117 water_delta = int(time.time()) - plant.last_water
118 water_left_pct = max(0, 1 - (water_delta/water_duration))
119 water_left = int(round(water_left_pct * indicator_squares))
120 return f"{water_left * '🟦'}{'⬛' * (indicator_squares - water_left)} {str(round(water_left_pct * 100))}% "
121
122def get_plant_description(plant: Plant):
123 output_text = ""
124 this_species = species_list[plant.species]
125 this_color = color_list[plant.color]
126 this_stage = plant.stage
127
128 if plant.dead:
129 this_stage = 99
130 try:
131 description_num = random.randint(0,len(stage_descriptions[this_stage]) - 1)
132 except KeyError as e:
133 print(e)
134 description_num = 0
135 # If not fully grown
136 if this_stage <= 4:
137 # Growth hint
138 if this_stage >= 1:
139 last_growth_at = plant.life_stages[this_stage - 1]
140 else:
141 last_growth_at = 0
142 ticks_since_last = plant.points - last_growth_at
143 ticks_between_stage = plant.life_stages[this_stage] - last_growth_at
144 if ticks_since_last >= ticks_between_stage * 0.8:
145 output_text += "You notice your plant looks different.\n"
146
147 output_text += get_stage_description(this_stage, description_num, this_species, this_color) + "\n"
148
149 # if seedling
150 if this_stage == 1:
151 species_options = [species_list[plant.species],
152 species_list[(plant.species + 3) % len(species_list)],
153 species_list[(plant.species - 3) % len(species_list)]]
154 random.shuffle(species_options)
155 output_text += f"It could be a(n) {species_options[0]}, {species_options[1]} or {species_options[2]}.\n"
156 # if young plant
157 if this_stage == 2:
158 if plant.rarity >= 2:
159 output_text += "You feel like your plant is special.\n"
160
161 # if mature plant
162 if this_stage == 3:
163 color_options = [color_list[plant.color],
164 color_list[(plant.color+3) % len(color_list)],
165 color_list[(plant.color-3) % len(color_list)]]
166 random.shuffle(color_options)
167 output_text += f"You can see the first hints of {color_options[0]}, {color_options[1]}, or {color_options[2]}.\n"
168
169 return output_text
170
171def get_art_filename(plant: Plant):
172 if plant.dead == True: return 'rip.txt'
173 if datetime.date.today().month == 10 and datetime.date.today().day == 31: return 'jackolantern.txt'
174 if plant.stage == 0: return 'seed.txt'
175 if plant.stage == 1: return 'seedling.txt'
176 if plant.stage == 2: return species_list[plant.species]+'1.txt'
177 if plant.stage == 3 or plant.stage == 5: return species_list[plant.species]+'2.txt'
178 if plant.stage == 4: return species_list[plant.species]+'3.txt'
179 return "template.txt"
180
181def get_plant_art(plant: Plant):
182 filename = get_art_filename(plant)
183 # Prints ASCII art from file at given coordinates
184 this_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "art")
185 this_filename = os.path.join(this_dir, filename)
186 this_file = open(this_filename,"r")
187 this_string = this_file.read()
188 this_file.close()
189 return this_string
190
191def get_plant_info(plant: Plant):
192 return f'''
193{get_plant_description(plant)}
194```{get_plant_art(plant)}```
195[{plant.name}, the {plant.parse_plant()}](tg://user?id={plant.owner})
196
197{get_plant_water(plant)}
198
199Bonus: x{plant.generation_bonus - 1}
200Points: {plant.points}
201'''