-
Notifications
You must be signed in to change notification settings - Fork 1
/
storefront.py
163 lines (144 loc) · 5.52 KB
/
storefront.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import json
import logging
import random
import datetime
from db import Database as db
log = logging.getLogger("storefront")
epicfilehandler = logging.FileHandler("store.log")
epicfilehandler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
log.setLevel(logging.DEBUG)
log.addHandler(epicfilehandler)
class NotEnoughSPError(Exception):
def __init__(self):
self.message = "Not enough SP to purchase item."
class NoItemError(Exception):
def __init__(self):
self.message = "That is not a store item."
class OutOfSeasonError(Exception):
def __init__(self):
self.message = "That is out of season."
class FreeFeedUsed(Exception):
def __init__(self):
self.message = "You already used your free cracker."
class AlreadyOwnedError(Exception):
def __init__(self):
self.message = "You already own that item."
class StoreLoader:
@staticmethod
def load_store(path="store.json"):
'''
Load store from a JSON file
'''
data = {}
try:
with open(path) as f:
data = json.load(f)
except:
log.exception("Failed to load Bonds JSON.")
return data
class StoreHandler:
store_list = StoreLoader.load_store()
@staticmethod
def __get_season():
thisMonth = datetime.datetime.now().month
if 3 <= thisMonth <= 5:
return "spring"
elif 6 <= thisMonth <= 8:
return "summer"
elif 9 <= thisMonth <= 11:
return "fall"
return "winter"
@staticmethod
def reload_store(path="store.json"):
'''
Reload store from disk
'''
StoreHandler.store_list = StoreLoader.load_store(path)
log.info("Reloading store from JSON.")
@staticmethod
def gamble_puzzle(item, com, unc):
'''
Takes odds for common, uncommon, and rare(implicit) win
and outputs appropriate AP to reward
'''
reward = StoreHandler.store_list["gifts"][item]["reward"]
rand = random.randint(1,100)
if 0 < rand <= com:
return {"type": "common", "value": reward["common"]}
elif com < rand <= com + unc:
return {"type": "uncommon", "value": reward["uncommon"]}
return {"type": "rare", "value": reward["rare"]}
@staticmethod
async def try_feed(user_id, user_sp, item):
'''
Checks if item exists and user has enough SP,
then sells and feeds the food item to Brie,
updating user db with new affection value,
and finally returns cost of food to subtract
'''
season = StoreHandler.__get_season()
seasonal_list = {**StoreHandler.store_list["base"], **StoreHandler.store_list[season]}
whole_list = {k:v for d_k in StoreHandler.store_list for k, v in StoreHandler.store_list[d_k].items()}
try_food = seasonal_list.get(item, None)
whole_try = whole_list.get(item, None)
if try_food is None and whole_try is None:
raise NoItemError
elif try_food is None:
raise OutOfSeasonError
if user_sp < try_food["cost"]:
raise NotEnoughSPError
await db.set_fed_brie_timestamp(user_id)
affection_to_add = try_food["affection"]
bond_to_add = try_food.get("bond", None)
curr_affection = await db.get_value(user_id, "affection")
if curr_affection + affection_to_add > 100:
affection_to_add = 100 - curr_affection
if item == "cracker":
free_feed_used = await db.get_value(user_id, "free_feed")
if free_feed_used == 1:
raise FreeFeedUsed
await db.set_value(user_id, "free_feed", 1)
await db.add_value(user_id, "affection", affection_to_add)
return 0
else:
await db.add_value(user_id, "bonds_available", 1)
await db.add_value(user_id, "affection", affection_to_add)
if bond_to_add is not None:
await db.add_value(user_id, "bond_level", bond_to_add)
return try_food["cost"]
@staticmethod
async def try_buy(user_id, user_sp, item):
'''
Unlocks a permanent item if the user has enough SP
'''
perma_items = StoreHandler.store_list["items"]
try_item = perma_items.get(item, "None")
if try_item == "None":
raise NoItemError
if user_sp < try_item["cost"]:
raise NotEnoughSPError
has_item = await db.get_value(user_id, f"has_{item}")
if has_item == 1:
raise AlreadyOwnedError
await db.set_value(user_id, f"has_{item}", 1)
return try_item["cost"]
@staticmethod
async def try_gift(user_id, user_sp, item):
'''
Gives Brie a gift and randomly gives the user
an amount of affection points. Returns the cost
and reward type.
'''
gifts = StoreHandler.store_list["gifts"]
try_gift = gifts.get(item, "None")
if try_gift == "None":
raise NoItemError
if user_sp < try_gift["cost"]:
raise NotEnoughSPError
reward = StoreHandler.gamble_puzzle(item, 60, 30)
affection_to_add = reward["value"]
curr_affection = await db.get_value(user_id, "affection")
if curr_affection + affection_to_add > 100:
affection_to_add = 100 - curr_affection
await db.add_value(user_id, "affection", affection_to_add)
return {"cost": try_gift["cost"], "reward": reward["type"]}