I'm creating a game (well, a plugin) where each player has a list of skills, each of which has an unique type object, each of which has a list of actions that need to be ran when a player executes his skills. I drew a diagram to show my classes: https://i.sstatic.net/NOdDF.jpg
And here's a quick mockup in pseudo-python:
class Player:
def __init__(self):
self.skills = []
def execute_actions(self, **event_args):
for skill in self.skills:
skill.execute_actions(player=self, **event_args)
class Skill:
def __init__(self, type_object, level):
self.type_object = type_object
self.level = level
@property
def name(self):
return self.type_object.name
def execute_actions(self, **event_args):
if self.level > 0:
self.type_object.execute_actions(skill=self, **event_args)
# more type_object properties
class SkillType:
def __init__(self, name, max_level):
self.name = name
self.max_level = max_level
self.actions = []
def execute_actions(self, **event_args):
for action in self.actions:
if action.event == event_args['event_name']:
action(**event_args)
class Action:
def __init__(self, event, callback, group=None, cooldown=None):
self.event = event
self.callback = callback
self.group = group
self._cooldown = cooldown
@property
def cooldown(self):
if self._cooldown is not None:
return self._cooldown
if self.group is not None:
return self.group.get('cooldown', None)
return None
# Usage
player = Player()
fireball = SkillType('Fireball', 5)
def fireball_deal_damage(skill, player, target, **event_args):
player.damage(target, skill.level)
fireball.actions.append(
Action('player_attack', fireball_deal_damage, cooldown=5)
)
player.skills.append(Skill(fireball, 1))
So, these skill types and actions are actually parsed from JSON:
// skills.json
[
{
"name": "Fireball",
"max_level": 5,
"actions": [
{
"event": "player_attack",
"action": "deal_damage",
"data": {"amount_base": 3, "amount_per_level": 1},
"cooldown": 5
}
]
}
]
The action above has a cooldown of five, which is easy enough to implement, just give each action a dictionary of type {Skill: time_when_last_used}
so it follows each Skill
instance's cooldown for that particular action.
The problem is, sometimes I need to have multiple actions that all use the same cooldown (maybe the fireball spell needs to deal damage and ignite the enemy, so that's two separate actions), so I came up with the idea of "groups":
// skills.json
[
{
"name": "Fireball",
"max_level": 5,
"actions": [
{
"event": "player_attack",
"action": "deal_damage",
"data": {"amount_base": 3, "amount_per_level": 1},
"group": 0
},
{
"event": "player_attack",
"action": "ignite",
"data": {"duration_base": 0, "duration_per_level": 1},
"group": 0
}
],
"groups": [
{ // Group 0
"cooldown": 5
}
}
]
Now some actions will use this group cooldown, so it's no longer as simple as giving each action instance a dictionary. Yet some actions will still use an individual cooldown rather than a "group" cooldown. How would I go on about implementing this?