# 1. Each skill has a "cooldowns" defaultdict which stores the cooldowns
# These cooldowns are then used directly in the skill methods
# Upsides: easy to read, easy to use
# Downsides: clutters the method and makes it harder to find out the skill's "actual" code
fail_message = SayText2('Remaining: {remaining}')
@callback('player_attack')
def _burn_victim(self, attacker, victim, **eargs):
cooldown = self.cooldowns[self._burn_victim] # replace with any key, as long as it's unique
if cooldown.remaining > 0:
fail_message.send(attacker.index, remaining=cooldown.remaining)
else:
victim.burn(duration=self.level)
cooldown.remaining = 10 - self.level
# 2. A cooldown decorator which takes two arguments, a cooldown callback and a fail_callback
# Upsides: versatile and keeps the function's body very clean. The callbacks can be separate methods instead of ugly lambdas
# Downsides: Let's be honest, most of the time: ugly lambdas. Even if not, extra methods in the class
fail_message = SayText2('Remaining: {f.remaining_cooldown}')
@callback('player_attack')
@cooldown(lambda self, **eargs: 10 - self.level,
fail_callback=lambda self, attacker, **eargs: fail_message.send(attacker.index, f=self._burn_victim))
def _burn_victim(self, victim, **eargs):
victim.burn(duration=self.level)
# 3. A simplified cooldown decorator which takes a fail_message instead of fail_callback
# Upsides: keeps the function's body very clean. Also keeps the decorator much cleaner from lambdas
# Downsides: not as versatile as the other two, as a message is always forced. Needs exact formatting in the message
fail_message = SayText2('Remaining: {skill._burn_victim.remaining_cooldown')
@callback('player_attack')
@cooldown(lambda self, **eargs: 10 - self.level, fail_message=fail_message)
def _burn_victim(self, victim, **eargs):
victim.burn(duration=self.level)