Skip to content

Commit d63b117

Browse files
authored
Add anti-active rule (#187)
* Add anti-active rule An anti-active rule is one that a user should strive to not trigger while it is "anti-active". If it is triggered, it will halve the user's points. * maybe we should stop using linters
1 parent c959e6d commit d63b117

File tree

1 file changed

+52
-12
lines changed

1 file changed

+52
-12
lines changed

bot/exts/levels/_cog.py

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,20 @@ class Levels(commands.Cog):
5656
def __init__(self, bot: SirRobin):
5757
self.bot = bot
5858

59+
self.rules_folder_path = Path("./bot/exts/levels/rules/")
60+
5961
self.rules_all = []
6062
self.rules_pool = []
61-
self.rules_active = []
62-
self.rules_folder_path = Path("./bot/exts/levels/rules/")
63+
self.rules_active = [] # Active rules earn the points
64+
self.rule_anti_active = [] # Anti-active rules will halve the current points
65+
6366
self.active_rules_num = 3
67+
self.anti_active_rules_num = 1
6468

6569
self.active_reaction_rule_triggers = []
6670
self.active_message_rule_triggers = []
71+
self.anti_active_message_rule_triggers = []
72+
self.anti_active_reaction_rule_triggers = []
6773

6874

6975
async def cog_load(self) -> None:
@@ -112,17 +118,19 @@ async def _load_rules(self) -> None:
112118
@tasks.loop(minutes=42.0)
113119
async def _cycle_rules_task(self) -> None:
114120
"""
115-
Change which rules are currently active.
121+
Change which rules are currently active and anti-active.
116122
117123
Rules will statistically be used before a repeat is seen.
118124
This is not a guarnatee though.
119125
"""
120-
if len(self.rules_pool) < self.active_rules_num:
126+
if len(self.rules_pool) < (self.active_rules_num + self.anti_active_rules_num):
121127
# If pool is empty, reshuffle completely to avoid activating same rule twice
122128
self.rules_pool = random.sample(self.rules_all, len(self.rules_all))
123-
self.rules_active = [self.rules_pool.pop() for _ in range(self.active_rules_num)]
124-
logger.debug(f"Cycled active rules to: {[rule.name for rule in self.rules_active]}")
125129

130+
self.rules_active = [self.rules_pool.pop() for _ in range(self.active_rules_num)]
131+
self.rules_anti_active = [self.rules_pool.pop() for _ in range(self.anti_active_rules_num)]
132+
logger.info(f"Cycled active rules to: {[rule.name for rule in self.rules_active]}")
133+
logger.info(f"Cycled anti-active rule(s) to: {[rule.name for rule in self.rules_anti_active]}")
126134

127135
self.active_message_rule_triggers = [
128136
rule_trigger for rule in self.rules_active
@@ -132,6 +140,16 @@ async def _cycle_rules_task(self) -> None:
132140
rule_trigger for rule in self.rules_active
133141
for rule_trigger in rule.rule_triggers if rule_trigger.interaction_type=="reaction"
134142
]
143+
144+
self.anti_active_message_rule_triggers = [
145+
rule_trigger for rule in self.rules_anti_active
146+
for rule_trigger in rule.rule_triggers if rule_trigger.interaction_type=="message"
147+
]
148+
self.anti_active_reaction_rule_triggers = [
149+
rule_trigger for rule in self.rules_anti_active
150+
for rule_trigger in rule.rule_triggers if rule_trigger.interaction_type=="reaction"
151+
]
152+
135153
self.all_message_rule_triggers = [
136154
rule_trigger for rule in self.rules_all
137155
for rule_trigger in rule.rule_triggers if rule_trigger.interaction_type=="message"
@@ -166,17 +184,20 @@ async def _calculate_point_thresholds_task(self) -> None:
166184
logger.debug(f"New thresholds: {thresholds}")
167185

168186

169-
async def _update_points(self, user_id: int, points: int) -> None:
187+
async def _update_points(self, user_id: int, points: int, halve_points: bool=False) -> None:
170188
"""Updates user's score and ensures correct role is assigned."""
171-
logger.debug(f"User {user_id} getting {points} points.")
189+
logger.debug(f"User {user_id} getting {points} points, halving override: {halve_points}.")
172190
if not await self.user_points_cache.contains(user_id):
173191
await self.user_points_cache.set(user_id, points)
174192
else:
175-
if points == 0:
193+
if points == 0 and not halve_points:
176194
return
177195

178196
current_points = await self.user_points_cache.get(user_id)
179197
new_point_total = current_points + points
198+
if halve_points:
199+
new_point_total = new_point_total // 2
200+
180201
await self.user_points_cache.set(user_id, new_point_total)
181202

182203
await self._update_role_assignment(user_id)
@@ -218,6 +239,8 @@ async def on_message(self, msg: discord.Message) -> None:
218239
if len(self.active_message_rule_triggers) == 0:
219240
return
220241

242+
user_id = msg.author.id
243+
221244
total_points = 0
222245
rule_matches = 0
223246
for rule_trigger in self.active_message_rule_triggers:
@@ -227,12 +250,21 @@ async def on_message(self, msg: discord.Message) -> None:
227250
total_points += rule_trigger.points
228251
rule_matches += 1
229252

253+
anti_active_rule_matches = 0
254+
for anti_active_rule_trigger in self.anti_active_message_rule_triggers:
255+
re_pattern = anti_active_rule_trigger.message_content
256+
match = re.search(re_pattern, msg.content)
257+
if match:
258+
anti_active_rule_matches += 1
259+
rule_matches += 1
260+
261+
halving_points = anti_active_rule_matches > 0
262+
230263
# Only update points if they've matched any rules
231264
# If they match multiple rules and earn 0 points,
232265
# that should still get them a role
233266
if rule_matches != 0:
234-
user_id = msg.author.id
235-
await self._update_points(user_id, total_points)
267+
await self._update_points(user_id, total_points, halve_points=halving_points)
236268

237269
total_rule_matches = 0
238270
for rule_trigger in self.all_message_rule_triggers:
@@ -270,11 +302,19 @@ async def on_reaction_add(self, reaction: discord.Reaction, user: discord.Member
270302
total_points += rule_trigger.points
271303
rule_matches += 1
272304

305+
anti_active_rule_matches = 0
306+
for anti_active_rule_trigger in self.anti_active_reaction_rule_triggers:
307+
if emoji_name in anti_active_rule_trigger.reaction_content:
308+
anti_active_rule_matches += 1
309+
rule_matches += 1
310+
311+
halving_points = anti_active_rule_matches > 0
312+
273313
# Only update points if they've matched any rules
274314
# If they match multiple rules and earn 0 points,
275315
# that should still get them a role
276316
if rule_matches != 0:
277-
await self._update_points(user.id, total_points)
317+
await self._update_points(user.id, total_points, halve_points=halving_points)
278318

279319

280320
@commands.group(name="levels")

0 commit comments

Comments
 (0)